Skip to content

Commit 153f652

Browse files
committed
chore(spec): regenerate the migration registry and liveness counts on the merged tree; reconcile the duration-rename D3 entry with the absorbed breaker half
The rename family's D3 entry (landed from the D3-per-family census) still prescribed `monitoringWindow` -> `monitoringWindowMs`; that renamed key is itself retired with the whole `health` block, so the entry now prescribes the trigger rename only and sends the breaker spelling to the removal. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QcAS3qiYYZNezaxZxaUdMV
1 parent 3af470d commit 153f652

3 files changed

Lines changed: 81 additions & 29 deletions

File tree

‎packages/spec/liveness/state-counts.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ for both corollaries.
4545
| `webhook` | 19 | 0 | 0 | 0 | 0 | 19 |
4646
| `query` | 16 | 0 | 0 | 5 | 0 | 21 |
4747
| `datasource` | 30 | 0 | 0 | 0 | 0 | 30 |
48-
| `app` | 47 | 0 | 0 | 9 | 0 | 56 |
48+
| `app` | 49 | 0 | 0 | 9 | 1 | 59 |
4949
| `book` | 20 | 0 | 0 | 1 | 0 | 21 |
5050
| `doc` | 15 | 0 | 0 | 0 | 0 | 15 |
5151
| `email_template` | 21 | 0 | 0 | 0 | 0 | 21 |
@@ -67,4 +67,4 @@ for both corollaries.
6767
| `sharing_rule` | 16 | 0 | 0 | 0 | 1 | 17 |
6868
| `connector` | 29 | 0 | 0 | 30 | 1 | 60 |
6969
| `analytics_cube` | 17 | 0 | 0 | 10 | 0 | 27 |
70-
| **total** | **931** | **5** | **1** | **154** | **11** | **1102** |
70+
| **total** | **933** | **5** | **1** | **154** | **12** | **1105** |

‎packages/spec/src/migrations/entries/semantic/18.connector-resilience-durations-unit-in-key.ts‎

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,42 @@ import type { SemanticMigration } from '../../types.js';
66
// unit in its NAME) — the D3 entry of the
77
// `connector-health-and-trigger-durations-unit-in-key` family (ruling B on
88
// #17152: one D3 entry per retirement family, even when D2 is lossless). The
9-
// two keys share one authored document and one conversion, so they share one
10-
// entry. Both renamed keys are still unread (the liveness ledger records each
11-
// as dead, `liveness/connector.json`): the rename is an honesty fix to the
12-
// declaration, and the entry says so rather than implying a live engine.
9+
// family was two keys in one authored document and one conversion:
10+
// `health.circuitBreaker.monitoringWindow` → `monitoringWindowMs` and
11+
// `triggers[].interval` → `intervalSeconds`.
12+
//
13+
// ⚠️ Reconciled with the connector resilience retirement (ADR-0049, the same
14+
// unreleased protocol step): the whole `health` block was then removed, so the
15+
// breaker half of this rename was ABSORBED — the renamed key is itself retired,
16+
// and the conversion now carries only the trigger half. This entry says so,
17+
// rather than prescribing a rename to a key the parse refuses next; the
18+
// removal's own judgement is the D3 entry `connector-resilience-keys-retired`.
19+
// `triggers[].interval` is still unread (the liveness ledger records it dead,
20+
// `liveness/connector.json`): the rename is an honesty fix to the declaration,
21+
// and the entry says so rather than implying a live engine.
1322
export const entry: SemanticMigration = {
1423
id: 'connector-resilience-durations-unit-in-key',
15-
surface: 'connector.health.circuitBreaker.monitoringWindow and connector.triggers[].interval — '
16-
+ 'the two connector durations whose name carried no unit',
17-
replacement: '`monitoringWindowMs` (milliseconds) and `intervalSeconds` (seconds) — rename each '
18-
+ 'key; both values are unchanged.',
19-
reason: 'The D2 conversion `connector-health-and-trigger-durations-unit-in-key` renames both keys '
20-
+ 'in `connectors[]` and on stored connector rows, keeping each value, with a separate notice '
21-
+ 'per key so an operator sees which of its own keys moved; the rename is lossless because '
22-
+ 'each key always meant the unit its new name states. Two judgments remain. First, the units '
23-
+ 'were easy to get wrong in opposite directions: `monitoringWindow` (milliseconds) sat one '
24-
+ 'key below `resetTimeoutMs`, and the bare token `interval` means MILLISECONDS elsewhere in '
25-
+ 'this same spec while a trigger interval meant SECONDS — so a trigger written '
26-
+ '`interval: 60000` for one minute asked for once every sixteen hours or so, and the rename '
27-
+ 'keeps 60000. Second, neither key drives an engine today: no polling loop reads a trigger '
28-
+ 'interval, and no circuit breaker exists for connectors, so nothing reads the monitoring '
29-
+ 'window. An author who relied '
30-
+ 'on either for behaviour has not been getting it, before or after this rename.',
31-
acceptanceCriteria: 'No connector carries `health.circuitBreaker.monitoringWindow` or '
32-
+ '`triggers[].interval`; the parse refuses both with the rename. Every `monitoringWindowMs` '
33-
+ 'value is the window the author intends in milliseconds and every `intervalSeconds` value '
34-
+ 'the cadence the author intends in seconds — a trigger meant to poll every minute reads '
35-
+ '`intervalSeconds: 60`. No part of the deployment\'s design depends on a connector polling '
36-
+ 'on that interval or tripping on that window: where it did, the author has moved that need '
37-
+ 'to a mechanism that runs.',
24+
surface: 'connector.triggers[].interval — the connector duration whose name carried no unit '
25+
+ '(and, until the whole `health` block was retired, connector.health.circuitBreaker.monitoringWindow)',
26+
replacement: '`intervalSeconds` (seconds) — rename the key; the value is unchanged. There is no '
27+
+ 'replacement for `monitoringWindow`: its renamed spelling `monitoringWindowMs` was retired with '
28+
+ 'the rest of `connector.health` — delete the block (see `connector-resilience-keys-retired`).',
29+
reason: 'The D2 conversion `connector-health-and-trigger-durations-unit-in-key` renames '
30+
+ '`triggers[].interval` in `connectors[]` and on stored connector rows, keeping the value; the '
31+
+ 'rename is lossless because the key always meant seconds. It used to rename the breaker\'s '
32+
+ '`monitoringWindow` too, but that half was absorbed by `connector-resilience-keys-removed`, '
33+
+ 'which strips the whole `health` block — so an author holding either `monitoringWindow` or '
34+
+ '`monitoringWindowMs` ends with no key at all, and must not re-add `monitoringWindowMs`: the '
35+
+ 'parse refuses the block. Two judgments remain for the trigger. First, the unit was easy to '
36+
+ 'get wrong: the bare token `interval` means MILLISECONDS elsewhere in this same spec while a '
37+
+ 'trigger interval meant SECONDS — so a trigger written `interval: 60000` for one minute asked '
38+
+ 'for once every sixteen hours or so, and the rename keeps 60000. Second, the key drives no '
39+
+ 'engine today: no polling loop reads a trigger interval, so an author who relied on it for '
40+
+ 'behaviour has not been getting it, before or after this rename.',
41+
acceptanceCriteria: 'No connector carries `triggers[].interval`; the parse refuses it with the '
42+
+ 'rename, and every `intervalSeconds` value is the cadence the author intends in seconds — a '
43+
+ 'trigger meant to poll every minute reads `intervalSeconds: 60`. No connector carries '
44+
+ '`health` in any spelling (`monitoringWindow` or `monitoringWindowMs` included). No part of '
45+
+ 'the deployment\'s design depends on a connector polling on that interval or tripping on a '
46+
+ 'breaker window: where it did, the author has moved that need to a mechanism that runs.',
3847
};

‎packages/spec/src/migrations/registry.ts‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7187,6 +7187,49 @@ const step18: MigrationStep = {
71877187
+ 'deliberately do NOT move, and a sweep that removed either has over-applied this entry: '
71887188
+ 'both resolve to real reads at the fetch site.',
71897189
},
7190+
// #15680 (stack card of #14478, maintainer ruling B: a duration key carries its
7191+
// unit in its NAME) — the D3 entry of the
7192+
// `connector-health-and-trigger-durations-unit-in-key` family (ruling B on
7193+
// #17152: one D3 entry per retirement family, even when D2 is lossless). The
7194+
// family was two keys in one authored document and one conversion:
7195+
// `health.circuitBreaker.monitoringWindow` → `monitoringWindowMs` and
7196+
// `triggers[].interval` → `intervalSeconds`.
7197+
//
7198+
// ⚠️ Reconciled with the connector resilience retirement (ADR-0049, the same
7199+
// unreleased protocol step): the whole `health` block was then removed, so the
7200+
// breaker half of this rename was ABSORBED — the renamed key is itself retired,
7201+
// and the conversion now carries only the trigger half. This entry says so,
7202+
// rather than prescribing a rename to a key the parse refuses next; the
7203+
// removal's own judgement is the D3 entry `connector-resilience-keys-retired`.
7204+
// `triggers[].interval` is still unread (the liveness ledger records it dead,
7205+
// `liveness/connector.json`): the rename is an honesty fix to the declaration,
7206+
// and the entry says so rather than implying a live engine.
7207+
{
7208+
id: 'connector-resilience-durations-unit-in-key',
7209+
surface: 'connector.triggers[].interval — the connector duration whose name carried no unit '
7210+
+ '(and, until the whole `health` block was retired, connector.health.circuitBreaker.monitoringWindow)',
7211+
replacement: '`intervalSeconds` (seconds) — rename the key; the value is unchanged. There is no '
7212+
+ 'replacement for `monitoringWindow`: its renamed spelling `monitoringWindowMs` was retired with '
7213+
+ 'the rest of `connector.health` — delete the block (see `connector-resilience-keys-retired`).',
7214+
reason: 'The D2 conversion `connector-health-and-trigger-durations-unit-in-key` renames '
7215+
+ '`triggers[].interval` in `connectors[]` and on stored connector rows, keeping the value; the '
7216+
+ 'rename is lossless because the key always meant seconds. It used to rename the breaker\'s '
7217+
+ '`monitoringWindow` too, but that half was absorbed by `connector-resilience-keys-removed`, '
7218+
+ 'which strips the whole `health` block — so an author holding either `monitoringWindow` or '
7219+
+ '`monitoringWindowMs` ends with no key at all, and must not re-add `monitoringWindowMs`: the '
7220+
+ 'parse refuses the block. Two judgments remain for the trigger. First, the unit was easy to '
7221+
+ 'get wrong: the bare token `interval` means MILLISECONDS elsewhere in this same spec while a '
7222+
+ 'trigger interval meant SECONDS — so a trigger written `interval: 60000` for one minute asked '
7223+
+ 'for once every sixteen hours or so, and the rename keeps 60000. Second, the key drives no '
7224+
+ 'engine today: no polling loop reads a trigger interval, so an author who relied on it for '
7225+
+ 'behaviour has not been getting it, before or after this rename.',
7226+
acceptanceCriteria: 'No connector carries `triggers[].interval`; the parse refuses it with the '
7227+
+ 'rename, and every `intervalSeconds` value is the cadence the author intends in seconds — a '
7228+
+ 'trigger meant to poll every minute reads `intervalSeconds: 60`. No connector carries '
7229+
+ '`health` in any spelling (`monitoringWindow` or `monitoringWindowMs` included). No part of '
7230+
+ 'the deployment\'s design depends on a connector polling on that interval or tripping on a '
7231+
+ 'breaker window: where it did, the author has moved that need to a mechanism that runs.',
7232+
},
71907233
// ADR-0049 enforce-or-remove — the D3 entry of the connector resilience family:
71917234
// `connector.health` (the `healthCheck` probe and the `circuitBreaker`),
71927235
// `connector.status` and the connector-nested `webhooks`, sixteen authorable keys

0 commit comments

Comments
 (0)