You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Claude-Session: https://claude.ai/code/session_01E5CYr5SDwe85gH2Jr5KSgu
Co-authored-by: Claude <noreply@anthropic.com>
|`filter.zod.ts` / `query.zod.ts`| 11+5 | open | query dialect — user data flows through; validated semantically elsewhere. `query.zod.ts` dropped one site in #4196: `FieldNodeSchema`'s nested-select object form was declared-but-inert and narrowed to `z.string()`, so the union's second member is gone. Four more left in #4286 with the `joins`/`windowFunctions` removals: `JoinNodeBaseSchema`, `WindowFunctionNodeSchema`, and `WindowSpecSchema`'s two blocks (outer + `frame`) were deleted with their clusters. Class unchanged |
| `datasource.zod.ts` | 8 | authorable | **strict as of #4001 data step** — all 8: `DatasourceSchema` (+ `pool` / `healthCheck` / `ssl` / `retryPolicy`), `ExternalDatasourceSettingsSchema` (+ `validation`), `DriverDefinitionSchema`. `config` stays `z.record` **at this level** by construction (per-driver shapes), but is no longer unchecked: **#4410** made `DatasourceSchema`'s refinement parse it against the contract for the declared driver (`driver/config-registry.zod.ts`), so the openness here is a shape this level cannot express rather than the absence of one. This row used to add "the driver's own `configSchema` validates them", which was false until #4410 landed the parse site it names. #4410 extended the same parse to each `readReplicas` entry; **#4468 retired that key** — no driver ever opened a replica connection and no query path splits reads from writes, so the entries were being checked against a contract nothing would apply. Strictness makes a dropped key loud; it cannot make a slot live, and a *precisely validated* dead slot is the more convincing lie | **#4583 dropped the ninth site**: `DatasourceCapabilities` is gone — eleven flags no code read, on a block whose strictness was the clearest case of this row's own closing sentence. `readOnly` in particular was *precisely validated* and completely inert, and had been relocated twice (#4410, #4465) toward somewhere it might be enforced; the shipped CRM example called a datasource a read replica on the strength of it while writes went through. Class unchanged
468
+
| `datasource.zod.ts` | 6 | authorable | **strict as of #4001 data step** — all 6: `DatasourceSchema` (+ `pool` / `ssl`), `ExternalDatasourceSettingsSchema` (+ `validation`), `DriverDefinitionSchema`. **#4583 B/C dropped two more sites**: the `healthCheck` and `retryPolicy` blocks are gone — nothing scheduled a probe and nothing retried, so their strictness was validating a shape no code consumed. `config` stays `z.record` **at this level** by construction (per-driver shapes), but is no longer unchecked: **#4410** made `DatasourceSchema`'s refinement parse it against the contract for the declared driver (`driver/config-registry.zod.ts`), so the openness here is a shape this level cannot express rather than the absence of one. This row used to add "the driver's own `configSchema` validates them", which was false until #4410 landed the parse site it names. #4410 extended the same parse to each `readReplicas` entry; **#4468 retired that key** — no driver ever opened a replica connection and no query path splits reads from writes, so the entries were being checked against a contract nothing would apply. Strictness makes a dropped key loud; it cannot make a slot live, and a *precisely validated* dead slot is the more convincing lie | **#4583 dropped the ninth site**: `DatasourceCapabilities` is gone — eleven flags no code read, on a block whose strictness was the clearest case of this row's own closing sentence. `readOnly` in particular was *precisely validated* and completely inert, and had been relocated twice (#4410, #4465) toward somewhere it might be enforced; the shipped CRM example called a datasource a read replica on the strength of it while writes went through. Class unchanged
469
469
| `driver/memory.zod.ts` / `driver/mongo.zod.ts` / `driver/postgres.zod.ts` | 6+1+1 | authorable | The per-driver shapes for the `config` slot — what an author actually writes under `datasource.config` (`host`, `port`, `filename`). **Undeclared here until the coverage walk went recursive** (see below): a subdirectory was invisible to the gate, so these sites sat outside the map while the map reported full coverage. **Strict as of #4410**, which is also what unblocked them: this row previously read "strictness here would enforce nothing" because nothing parsed `datasource.config` against these schemas and both `*DriverSpec.configSchema` literals were `{}`. Now `DatasourceSchema` parses `config` against them, and the same schemas project onto `configSchema` and onto the Studio connection form. (#4410 also ran the parse over each `readReplicas` entry; #4468 retired that key outright — see the row above.) `postgres.zod.ts` drops a site: its `ssl` was a `boolean | {ca, cert, key, …}` union, and the object arm is gone — certificates now live in the datasource-level `ssl` block (declared, strict, and until #4410 read by nobody), leaving `config.ssl` as the on/off shorthand. That narrowing is forced by the same projection: the Studio form renders anything that is not boolean/enum/number as a TEXT INPUT, so a union here would have produced a wizard whose every `ssl` value the new gate rejects. `memory.zod.ts` keeps 6 but loses two KEYS — `indexes` / `maxRecordsPerObject`, which `InMemoryDriverConfig` has no field for, removed under ADR-0049 rather than blessed by the new gate |
470
470
|`driver/mysql.zod.ts` / `driver/sqlite.zod.ts`| 1+2 | authorable | The rest of the `config` contract, added by #4410. `mysql.zod.ts` and `sqlite.zod.ts` (sqlite + sqlite-wasm) are shapes that **never existed** — both driver ids were offered by the connection form and buildable by the shared factory, with no config contract anywhere, so `driver: 'sqlite'` + a misspelled `filename` was an ephemeral `:memory:` database reported as configured. All three sites strict, same error factory as the rest of the campaign. (Their sibling `driver/common.zod.ts` holds shared enums and prescription strings and has no `z.object(` site, so the coverage gate skips it) |
Copy file name to clipboardExpand all lines: docs/protocol-upgrade-guide.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -189,6 +189,7 @@ The `script` flow node converges on its one real path (#4343). It had four ways
189
189
|`flow-node-wait-timeout-keys-removed`|`flow.node.waitEventConfig`| waitEventConfig keys 'timeoutMs' (→ 'timerDuration', stringified — its only reader used it as the duration) and 'onTimeout' (removed — zero readers, so no timeout ever fired) (#4158) | retired — `migrate meta` only |
190
190
|`datasource-read-replicas-removed`|`datasource.readReplicas`| datasource key 'readReplicas' removed (#4468 — no driver opened a replica connection and no query path splits reads from writes; front replicas behind one endpoint and point `config` at it) | retired — `migrate meta` only |
191
191
|`datasource-capabilities-removed`|`datasource.capabilities`| datasource key 'capabilities' removed (#4583 — eleven flags no code read; pushdown comes from the driver's own supports.*, and `readOnly` never made anything read-only) | retired — `migrate meta` only |
192
+
|`datasource-inert-blocks-removed`|`datasource.retryPolicy / datasource.healthCheck / datasource.external.label / datasource.external.requirePermission`| datasource keys 'retryPolicy'/'healthCheck' and external 'label'/'requirePermission' removed (#4583 — nothing retried, nothing probed on a schedule, and the federation label/permission were read by nobody) | retired — `migrate meta` only |
192
193
|`flow-node-script-branch-keys-removed`|`flow.node.script.config.actionType / flow.node.script.config.template / flow.node.script.config.recipients / flow.node.script.config.variables / flow.node.script.config.script`| script flow-node config keys 'actionType' (→ 'function' when it was shorthand for one; otherwise removed — 'email'/'slack' were logger-backed stubs that delivered nothing), plus 'template' / 'recipients' / 'variables' (fed those stubs) and 'script' (inline JS the runtime never executed) (#4343) | retired — `migrate meta` only |
193
194
194
195
### Semantic (delegated to you, with acceptance criteria)
0 commit comments