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
[#14478 stack 2/6] api/: the 12 remaining duration keys carry their unit in the key name — ADR-0087 conversions with readers, ApiError.retryAfter with its own BREAKING note #15677
Part of #14478 — follow-on card 2 of 6, filed by the domain:spec seat (session_01M59rPZZFzqhfMUPFqqZTkf, 2026-09-05T02:55Z) under the maintainer ruling B on #14478 (5548763981, batch #43, 「同意」). Dispatched only after stack card 1/6 (the EpochMs schema and the externalVocabulary marker) has a PR to stack on.
Ruling text this card executes (verbatim)
Convert the ~30 authored config durations and the ~16 runtime-emitted measurements (they are read by humans and agents even if not authored; ApiError.retryAfter on the wire envelope included, with its own BREAKING note).
(1) the gate's own predicate is the population's definition — the 70/65 reading is authoritative […]; write the predicate into the follow-on cards so nobody recounts by another rule.
The predicate
Run pnpm --filter @objectstack/spec check:duration-unit-keys on the stacked head; a property whose value is a z.number() / z.int() / z.coerce.number() chain and whose .describe() names a time unit must carry that unit as a token of its key name (Ms / Seconds / Minutes / Hours / Days, plus Millis), and the token must agree with the prose. ⛔ The list below is the gate's own output on e68ae2b58 (PR #15626's head), filtered to src/api/** minus card 1/6's instants and marked keys; re-derive on the stacked head before editing.
site (e68ae2b58)
key
describe unit
gate's suggested name
src/api/contract.zod.ts:403
cacheTtl
seconds
cacheTtlSeconds
src/api/endpoint.zod.ts:186
cacheTtl
seconds
cacheTtlSeconds
src/api/errors.zod.ts:394
retryAfter
seconds
retryAfterSeconds — ⚠️ the ADR-0112 wire envelope; ruled IN with its own BREAKING note (the HTTP Retry-After header is a separate, unchanged surface)
src/api/plugin-rest-api.zod.ts:202
timeout
ms
timeoutMs
src/api/plugin-rest-api.zod.ts:205
cacheTtl
seconds
cacheTtlSeconds
src/api/plugin-rest-api.zod.ts:717
defaultCacheTtl
seconds
defaultCacheTtlSeconds
src/api/router.zod.ts:98
timeout
ms
timeoutMs
src/api/websocket.zod.ts:421
reconnectInterval
ms
reconnectIntervalMs
src/api/websocket.zod.ts:423
pingInterval
ms
pingIntervalMs
src/api/websocket.zod.ts:424
timeout
ms
timeoutMs
src/api/websocket.zod.ts:562
heartbeatInterval
ms
heartbeatIntervalMs
(11 rows above; the gate's twelfth api/ row, auth-endpoints.zod.ts:287 interval, is an external-vocabulary key handled by card 1/6 — if card 1/6's verification finds it is NOT a standard's name, it returns here as a rename.)
Stacked: branch off the head of stack card 1/6's branch; draft PR, base = that branch; body first line Part of #14478, this card named without a closing keyword. ⛔ Never Fixes #14478.
Clause-②: yes ⇒ needs:contract-review on PR and card at creation (dual carrier). Changeset: @objectstack/specminor, BREAKING banner naming every renamed key, adr-0087: registered with the ids; readers' packages patch/minor as derived.
packages/spec/src/migrations/registry.ts is written by this stack only; the stack is serial (2 → 3 → 4 → 5 → 6).
Part of #14478 — follow-on card 2 of 6, filed by the
domain:specseat (session_01M59rPZZFzqhfMUPFqqZTkf, 2026-09-05T02:55Z) under the maintainer ruling B on #14478 (5548763981, batch #43, 「同意」). Dispatched only after stack card 1/6 (theEpochMsschema and theexternalVocabularymarker) has a PR to stack on.Ruling text this card executes (verbatim)
The predicate
Run
pnpm --filter @objectstack/spec check:duration-unit-keyson the stacked head; a property whose value is az.number()/z.int()/z.coerce.number()chain and whose.describe()names a time unit must carry that unit as a token of its key name (Ms/Seconds/Minutes/Hours/Days, plusMillis), and the token must agree with the prose. ⛔ The list below is the gate's own output one68ae2b58(PR #15626's head), filtered tosrc/api/**minus card 1/6's instants and marked keys; re-derive on the stacked head before editing.e68ae2b58)src/api/contract.zod.ts:403cacheTtlcacheTtlSecondssrc/api/endpoint.zod.ts:186cacheTtlcacheTtlSecondssrc/api/errors.zod.ts:394retryAfterretryAfterSeconds—Retry-Afterheader is a separate, unchanged surface)src/api/plugin-rest-api.zod.ts:202timeouttimeoutMssrc/api/plugin-rest-api.zod.ts:205cacheTtlcacheTtlSecondssrc/api/plugin-rest-api.zod.ts:717defaultCacheTtldefaultCacheTtlSecondssrc/api/router.zod.ts:98timeouttimeoutMssrc/api/websocket.zod.ts:421reconnectIntervalreconnectIntervalMssrc/api/websocket.zod.ts:423pingIntervalpingIntervalMssrc/api/websocket.zod.ts:424timeouttimeoutMssrc/api/websocket.zod.ts:562heartbeatIntervalheartbeatIntervalMs(11 rows above; the gate's twelfth
api/row,auth-endpoints.zod.ts:287 interval, is an external-vocabulary key handled by card 1/6 — if card 1/6's verification finds it is NOT a standard's name, it returns here as a rename.)Execution notes
retiredKey()tombstone on the old spelling carrying the rename prescription, D2 entry (+ theos migratestep) where the key is on the authorable surface (RETIRED_KEYS_BY_MAJORrow), a semantic entry where it is not; every reader in every workspace package moved in the same PR at the same magnitude (grep by TYPE, not by name — the feat(spec)!: duration-shaped number keys carry their unit in the key name — no-baseline gate + seven ADR-0087 renames (timeoutMs, ttlSeconds/ttlMs, *TimeoutSeconds) #15626 fix lap's lesson); liveness ledgers, forms, i18n bundles, docs andskills/**prose updated where they name the key (askills/**hit makes the PR governed: keep it, do not drop it to escape governance).Part of #14478, this card named without a closing keyword. ⛔ NeverFixes #14478.Clause-②: yes⇒needs:contract-reviewon PR and card at creation (dual carrier). Changeset:@objectstack/specminor, BREAKING banner naming every renamed key,adr-0087: registeredwith the ids; readers' packages patch/minor as derived.packages/spec/src/migrations/registry.tsis written by this stack only; the stack is serial (2 → 3 → 4 → 5 → 6).Related: #14478 · PR #15626 · stack 1/6.
Generated by Claude Code