feat(spec)!: datasource 死键归零 —— 退役 retryPolicy / healthCheck / external 两键(#4583 批 B/C/D) - #4629
Merged
Merged
Conversation
…nert keys (#4583 B/C/D) The last nine dead properties on `datasource`, all authorWarn'd, none bridgeable — each already had a DIFFERENT live mechanism doing the job it appeared to configure: - `retryPolicy` (4 keys): no connect or query path retried on it. Connection failure is the boot policy in the datasource connection service (degraded boot / bootCritical fail-fast), which does not retry on a schedule. - `healthCheck` (3 keys): nothing scheduled a probe, so `enabled` enabled nothing. Liveness is probed ON DEMAND via the driver handle's ping() / checkHealth(). Not to be confused with external.validation.checkIntervalMs, the one recurring datasource timer, which checks SCHEMA DRIFT. - `external.label`: the federation block never had a display name of its own; Setup renders the top-level `label`. - `external.requirePermission`: no authorization check consulted it. Federated access is governed by ordinary object permission sets + RLS — naming a permission that is never required is the false-compliance shape ADR-0049 removes. The retryPolicy rejection deliberately does NOT offer a rename. hook.retryPolicy and job.retryPolicy ARE enforced, but they are a different key on a different type and spell the delay `backoffMs`, not `baseDelayMs` — and that inconsistency is itself the evidence nothing read the datasource one, since no code reads both spellings. #4488 named this the sharpest trap in the type; the prescription and a test both pin it. Committed as one change rather than three: B/C/D share a single ADR-0087 conversion (house style for multi-key removals — `surface` carries all four clauses), one ledger, one README row and one set of regenerated artifacts, so split commits would each fail their own gates. The three changesets keep the release-note granularity the issue asked for. Also fixes a test that used `external: { label: … }` only to make the block non-empty — `external: {}` says what it meant. datasource liveness ledger: 9 dead -> 0. It was seeded with 20, the highest dead ratio of any governed type. Strictness-ledger site count 8 -> 6, data/ 164 -> 162. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5CYr5SDwe85gH2Jr5KSgu
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
os-zhuang
marked this pull request as ready for review
August 2, 2026 12:18
os-zhuang
enabled auto-merge
August 2, 2026 12:18
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This was referenced Aug 2, 2026
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.
#4583 的批 B/C/D,也是最后一批。批 A(
capabilities)已由 #4601 合并。合并后
datasource的活性账本死键归零 —— 它当初以 20 条 dead 被纳入治理,是所有受治理类型里比例最高的一个。九个键,全部 remove 而非 enforce
不是因为"用得少",而是因为每一个都已经有另一套 live 机制在做它看起来在配置的那件事:
retryPolicy.{maxRetries,baseDelayMs,maxDelayMs,backoffMultiplier}bootCriticalfail-fast)。它不按计划重试,所以maxRetries: 5从来没改变过任何行为healthCheck.{enabled,intervalMs,timeoutMs}enabled: true什么也没启用。存活是 driver handle 的ping()/checkHealth()按需探测,Setup 的「测试连接」调的就是它external.labellabel。showcase 两个都声明了,现在只留会显示的那个external.requirePermissionretryPolicy的报错刻意不提供改名建议这是 #4488 点名的、这个类型里最险的一个陷阱,而它是命名碰撞而非行为疑问:
hook.retryPolicy和job.retryPolicy是真被强制执行的。但它们是另一个类型上的另一个键,延迟拼作backoffMs,不是baseDelayMs。而这个拼写不一致本身,就是"没人读 datasource 那个"的证据 —— 全仓没有任何代码同时读两种拼写。
所以:conversion 只碰
datasources,schema 的报错把这个区别讲清楚而不是给一个改名,并且有测试钉住报错文案必须同时包含backoffMs与hook/job。一条把作者引向"另一个类型的同名键"的处方,比没有处方更糟。为什么是一个 commit 而不是三个
三批共用同一条 ADR-0087 conversion(
datasource-inert-blocks-removed,多键移除的 house style,surface用/承载四个子句)、同一份账本、同一行 README、同一批重新生成的产物 —— 拆开的话每个中间 commit 都过不了自己的闸门。三个 changeset 保留了 issue 要求的发布说明粒度。conversion 里有一处值得看:
external.*是嵌套键,而stripKeys只处理顶层,所以apply()单独下钻一层并 copy-on-write(expectedNotices: 4,嵌套的两个也各算一条)。验证
retryPolicy/healthCheck/external.label/external.requirePermission各自被拒;healthCheck那条还断言报错提到ping|checkHealth且提到checkIntervalMs(后者是唯一的周期性 datasource 定时器,检查的是schema 漂移而非存活,不能混淆)hook.retryPolicy/job.retryPolicy仍正常 parse,showcase 的 jobs/hooks 未受影响pnpm build/test(132/132 全绿)/typecheck/lintcheck:generated、check:liveness、check:empty-state、check:variant-docs、check:strictness-ledger、check:i18n、check-slot-lookup-ratchetdata/段 164 → 162content/docs/releases/顺带修的两处
external: { label: … }只是为了让块非空 —— 现在写external: {},说的就是它本来的意思。lint-liveness-properties.test.ts按设计跑在真实 shipped 账本上,所以每次删 datasource 账本行都会反转它的一条断言。它在批 A 和这一批各翻了一次,现在收敛成断言零发现,并保留作回归钉:将来若有人重新引入一个 dead+authorWarn 的 datasource 属性,会在这里红,而不是悄悄发出去。收尾
这批合并后 #4583 四批全部完成,可以关闭。#4584(managed datasource 到底该不该有只读闸门)是批 A 里刻意不就地发明机制而留下的决策位 —— 照 #4479 的先例。
Generated by Claude Code