@@ -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.
1322export 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} ;
0 commit comments