Split out of #14478 by triage. #14478 inventoried three shapes of duration-shaped z.number() key in packages/spec; two of them can only be resolved by renaming published keys or adding a new gate, both of which are maintainer calls, and #14478 keeps that ruling. This card is the third shape, which needs no ruling at all — it is a plain publication defect with a one-line fix per key, and it should not sit behind the ruling.
Measured at origin/main ed44512
packages/spec/src/system/tenant.zod.ts:
/**
* Idle pool timeout in seconds
*/
idleTimeout: z.number().int().positive().default(300).describe('Idle pool timeout'),
/**
* Session timeout in seconds
*/
sessionTimeout: z.number().int().positive().default(3600).describe('Session timeout'),
:552 and :672. In both cases the JSDoc immediately above carries the unit and the .describe() string drops it.
Why that specific asymmetry is the defect
.describe() is what content/docs/references/** publishes; the JSDoc is not. So the one reader who most needs the unit — someone reading the published reference page rather than the source — is the only reader who does not get it. They see a key named idleTimeout, a default of 300, and the words "Idle pool timeout". 300 is a plausible number of seconds and a plausible number of milliseconds, and nothing on the page decides it.
Both keys are on the authorable surface, so this is a value a customer can set wrong by a factor of 1000 with no signal.
Fix
Add the unit to the two .describe() strings, matching the JSDoc directly above them ('Idle pool timeout in seconds', 'Session timeout in seconds'). Nothing else — no rename, no schema change, no gate.
This does not change accept/reject behaviour and does not widen the public surface: the accepted values are identical before and after. It is the published prose catching up to the source of truth one line above it.
Explicitly NOT in scope
Refs: #14478 (parent inventory and the ruling half), #13801 (the sibling misread — clock, not magnitude).
Generated by Claude Code
Split out of #14478 by triage. #14478 inventoried three shapes of duration-shaped
z.number()key inpackages/spec; two of them can only be resolved by renaming published keys or adding a new gate, both of which are maintainer calls, and #14478 keeps that ruling. This card is the third shape, which needs no ruling at all — it is a plain publication defect with a one-line fix per key, and it should not sit behind the ruling.Measured at
origin/mained44512packages/spec/src/system/tenant.zod.ts::552and:672. In both cases the JSDoc immediately above carries the unit and the.describe()string drops it.Why that specific asymmetry is the defect
.describe()is whatcontent/docs/references/**publishes; the JSDoc is not. So the one reader who most needs the unit — someone reading the published reference page rather than the source — is the only reader who does not get it. They see a key namedidleTimeout, a default of300, and the words "Idle pool timeout".300is a plausible number of seconds and a plausible number of milliseconds, and nothing on the page decides it.Both keys are on the authorable surface, so this is a value a customer can set wrong by a factor of 1000 with no signal.
Fix
Add the unit to the two
.describe()strings, matching the JSDoc directly above them ('Idle pool timeout in seconds','Session timeout in seconds'). Nothing else — no rename, no schema change, no gate.This does not change accept/reject behaviour and does not widen the public surface: the accepted values are identical before and after. It is the published prose catching up to the source of truth one line above it.
Explicitly NOT in scope
ttlkeys with different units fourteen lines apart (kernel/metadata-loader.zod.ts:82seconds vs:96milliseconds) — those describes DO name their units; the problem there is the key naming, which is a rename of published keys. Stays on spec: duration-shaped number keys carry their unit in describe prose only — twottlkeys with different units in one block, baretimeoutkeys, unit-less tenant timeouts #14478.timeoutkeys (data/hook.zod.ts:306,system/job.zod.ts:142,data/driver.zod.ts:23) — same reason. Stays on spec: duration-shaped number keys carry their unit in describe prose only — twottlkeys with different units in one block, baretimeoutkeys, unit-less tenant timeouts #14478.ttlkeys with different units in one block, baretimeoutkeys, unit-less tenant timeouts #14478.Refs: #14478 (parent inventory and the ruling half), #13801 (the sibling misread — clock, not magnitude).
Generated by Claude Code