fix(objectql): 让开门广告停止在它不成立的地方发声(#3438 收尾) - #4284
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
os-zhuang
force-pushed
the
claude/d1-d2-strict-default-flip-vbly5z
branch
from
July 31, 2026 03:23
267b9af to
e1efec8
Compare
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 14 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…false (#3438) The boot line that names an open value-shape gate (#4253) fired on every deployment there is, and stated something untrue on any deployment that had already settled the posture with an environment switch. Both are one failure: an advisory that speaks where it does not apply is exactly how readers learn to ignore it, and the line's whole value is that a warn-first deployment is told once, credibly, which command ends warn mode. Neither defect is reachable from the suite that shipped with the announcement. `engine.test.ts` mocks `./registry`, and a mocked registry hands the engine exactly the fields the test wrote — so these cases get a sibling file built on the genuine `registerApp → registry` path, which is the only way a test sees what a deployment sees. `objectHasCoveredValueField` — the dormancy short-circuit meant to spare an object with no covered field the flag query — tested raw type membership, while the real registry INJECTS covered-type fields into every object it registers: `organization_id` and `owner_id` (both `system`), `created_by` and `updated_by` (both in `SKIP_FIELDS`), four `lookup`s. `validateRecord` skips every one of them before it reaches the value-shape check, so the short-circuit answered `true` for literally every object, never fired, and its WeakMap memoized a constant. It now counts by the validator's own `isScannableValueShapeField` — the predicate the scanner already imports. Three readings of "a covered field" drifting by one clause is how a gate ends up governing fields nothing enforces, which is the shape #4235 argued against. The announcement also consulted no environment switch, though both postures it reports on short-circuit ahead of the deployment flag it reads. Under `OS_DATA_VALUE_SHAPE_STRICT_ENABLED` enforcement is already on for both classes, so "checked but NOT enforced here" was false; under either opt-out the operator chose leniency deliberately, so naming a migration that cannot change what they get is noise. Each gate consults its own pair — `mediaPostureSetByEnv` and `valueShapePostureSetByEnv`, siblings for the reason `mediaStrictEffective` and `valueShapeStrictEffective` are siblings, since the opt-outs are per-class while the opt-in opens both. Cheapest test first, so a kernel with nothing to say still reaches no flag query. Enforcement is unchanged: same gates, same flags, same default. The flag read was already memoized per process, so what this corrects is the property ADR-0104 states, not a user-visible cost. The predicate fix is pinned by reverting it: with raw-type membership restored, `stays silent when no object declares a covered field` fails, because a `note` declaring only text still carries the four injected lookups. Verified on a full workspace build: objectql 1345 (7 new), cli 628, spec check:generated 8/8, check:release-notes and check:doc-authoring pass, ESLint clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016zgA8CQMJeJbFEjnbib1Uv
os-zhuang
force-pushed
the
claude/d1-d2-strict-default-flip-vbly5z
branch
from
July 31, 2026 03:45
e1efec8 to
76a72c8
Compare
os-zhuang
marked this pull request as ready for review
July 31, 2026 04:04
os-zhuang
added a commit
that referenced
this pull request
Jul 31, 2026
…ly landed (#3438) (#4299) The 2026-07-30 addendum's rollout bullet says `os migrate meta --from 16` ends by naming the two data migrations "with their gate status". The implementation (#4253) deliberately names them without it, and the reasoning lived only in that PR's commit message — so the decision record kept prescribing the wrong half to the next implementer, and already misled one (#4284's first draft built exactly what the sentence says). The status half was a category error this ADR had already corrected two addenda earlier: per the 2026-07-27 addendum the evidence gate is per DEPLOYMENT, and `meta` acts on SOURCE, which deploys to zero-or-N deployments — so "its" gate status has no referent at meta time. Best-effort status (show it when a datastore happens to be reachable) would be worse than none: silence goes ambiguous, output turns environment-dependent, and the command gains a hang path on an unreachable database. Status is reported where a datastore is actually open — each migration command reports before it writes, and the boot line carries the live verdict, which after #4284 speaks only where it is true. Amended in place with the ADR's own convention (the L428-style dated inline parenthetical), original text preserved. Empty changeset per the adr-0104-attestation-adr-note precedent. Releases nothing. Claude-Session: https://claude.ai/code/session_016zgA8CQMJeJbFEjnbib1Uv Co-authored-by: Claude <noreply@anthropic.com>
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
范围已经变了:广告本身被 #4253 抢先落地,本 PR 缩为修它的两个缺陷
这个 PR 原本做的是 ADR-0104 rollout 要求的两处广告位。开着的时候 #4253 把同一件事合进了 main(
3ec8186cb),os migrate meta的收尾列表和 boot 那一行都已经在了,而且它挂在kernel:bootstrapped而非 ready 路径上——刻意避开 storage ready 的竞态,比我原来的位置对。我的那份实现已全部撤掉,改用 main 的。留下的是两个真实缺陷,都在 #4253 刚落地的那行广告上,且都无条件发生在生产里。
一、那行广告在每一个部署上都响
objectHasCoveredValueField——本应让「没有被覆盖字段的对象不必付出标记查询」的休眠短路——按原始类型判断,而真实 registry 会给它注册的每个对象注入被覆盖类型的字段:organization_id与owner_id(都是system)、created_by与updated_by(都在SKIP_FIELDS),四个lookup。validateRecord在到达值形态检查之前把它们逐个跳过,于是这个短路对存在的每一个对象答 true,从未生效,它的 WeakMap 缓存的是一个常量。改为使用校验器自己的
isScannableValueShapeField——扫描器早就 import 的那个谓词。「什么算被覆盖字段」的三份读法差一个子句,正是一个门禁最终去治理无人执行的字段的方式,也正是 #4235 自己论证过要防的形状。二、那行广告在环境开关已经定调时说假话
广告完全不看环境变量,而它所报告的两个姿态都在部署标记之前短路:
OS_DATA_VALUE_SHAPE_STRICT_ENABLED=1→VALUE_SHAPE_STRICT()让两个*StrictEffective直接返回 strict。此时「checked but NOT enforced here」是假话。OS_ALLOW_LAX_VALUE_SHAPES=1/OS_ALLOW_LAX_MEDIA_VALUES=1→ 运维主动选了宽松,跑那个迁移不会改变他得到的东西,指着它就是噪音。两个门禁各查自己那一对(
mediaPostureSetByEnv/valueShapePostureSetByEnv),因为两个 opt-out 是分类的、而 opt-in 同时打开两类;做成兄弟函数的理由与mediaStrictEffective/valueShapeStrictEffective是兄弟一致。判定按代价从低到高,没什么可播报的内核仍然到不了标记查询。为什么 #4253 自己的测试抓不到这两个
engine.test.ts里vi.mock('./registry')——mock 掉的 registry 只会把测试自己写的字段交给引擎,那四个注入的 lookup 根本不存在,环境开关也没有被覆盖。所以这些用例放在独立文件里,走真实registerApp → registry路径,这是测试能看见部署所看见之物的唯一方式。回归守卫已取证:把谓词改回原始类型写法,
stays silent when no object declares a covered field立刻转红(只声明 text/textarea 的note照样触发广告);改回来即绿。#4253 的 125 条测试在本 PR 下全部照常通过。执行语义没有任何变化:同样的门禁、同样的开关、同样的默认值。标记读取本就按进程记忆化,所以这修正的是 ADR 声明的性质,而非用户可见的开销。
改动范围
相对 main 只有 5 个文件:
packages/objectql/src/engine.tspackages/objectql/src/validation/record-validator.tsvalueShapePostureSetByEnv/mediaPostureSetByEnv(+35)packages/objectql/src/value-shape-scan-advisory.test.ts.changeset/adr-0104-gate-announcement-tells-the-truth.mdcontent/docs/releases/v17.mdx验证
全量 workspace 构建后:
@objectstack/objectql@objectstack/clispec check:generatedcheck:release-notes/check:doc-authoring关联
#3438 的工作项 2 尾部。广告位本体由 #4253 落地,本 PR 修它的两个缺陷;工作项 1(D2 翻转)与工作项 3(新库创建时记账)已分别落地。本 PR 合入后 #3438 可关闭。
一处留给维护者定夺:ADR-0104 第 826–833 行仍写着
os migrate meta会显示门禁状态,而 #4253 有意没这么做(该命令不开数据库)。理由在它的提交说明里,决策记录本身仍未修订——是否改 ADR 那句请你定。