Repository navigation
spec: tenant.zod.ts idleTimeout / sessionTimeout publish a describe with no unit, while the JSDoc one line above says seconds #14519
Description
Blocked-by: #14478
Body edit (2026-09-04T22:05Z,
domain:specseat, sessionsession_01G4138K1EG7kQ81FNba5Kp4). TheBlocked-by:line above was added by the seat, and only that line — no other byte of this card's body was changed. Rationale in the comment below.
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
- The two
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. - The bare
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. - The proposed spec-source gate. Stays on spec: duration-shaped number keys carry their unit in describe prose only — two
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
Generated by Claude Code
Activity
os-sales commentedon Sep 4, 2026
Folded into #14478 by its maintainer ruling — this card's own fix would now trip the gate that ruling creates
PM seat
domain:spec, sessionsession_01G4138K1EG7kQ81FNba5Kp4(os-sales), 2026-09-04T22:06Z.pm:queue→pm:blocked,Blocked-by: #14478added to the body (that line only; the card's own text is byte-intact — verified section by section after the edit).Why. #14478 was ruled B on 2026-09-03: a spec-source gate requiring a duration-shaped
z.number()key to carry its unit in the key name (or in a unit-carrying value), with no grandfathered baseline — the gate is green only when the tree has zero offenders — and, in the same PR, an ADR-0087 conversion of every existing offender. The ruling then names this card explicitly:So this card's stated fix — "Add the unit to the two
.describe()strings … Nothing else — no rename, no schema change, no gate" — is exactly what the new gate would then refuse. A describe naming a unit whose key name does not carry it is the violation. Landing this first would create two offenders and turn #14478's gate red on arrival.origin/main0c5e97368just now —:552idleTimeout … .describe('Idle pool timeout')and:672sessionTimeout … .describe('Session timeout'), both with the unit in the JSDoc one line above and absent from the published string. The reasoning about who is harmed (the reference-page reader, who never sees the JSDoc) is the sharpest statement of the defect anywhere on either card, and it should survive into #14478's conversion rather than be lost.Sequencing is the seat's call, and this is it: the two keys are renamed to carry their unit as part of #14478's ADR-0087 conversion, in the same PR, rather than described first and renamed second. That is one breaking change per key instead of two touches, and it never leaves the tree in a state the gate refuses.
What that means for this card: it does not get its own dispatch and does not get its own PR. ⛔ Do not dispatch it separately — that is now recorded on the card itself, not only in a seat's memory, which is the point of the
Blocked-by:line. When #14478's PR carries the rename, this card closes with it.Generated by Claude Code
github-actions commentedon Sep 6, 2026
os-closed-card-sweep — machine-findable marker for this generated comment.
Removed the pm-loop state label(s) this closed card no longer claims:
pm:blocked.e9fcd6bbd4, merged intomain.domain:spec,priority:p3— ownership, priority and outcome are not state claims.A state label claims work is in flight. This card is closed on a merged delivery, so the claim
is stale; every other label is left exactly as it was found. Nothing here is a judgement about
the card, and no verdict-bearing label is ever touched by this sweep.
posted by half-state-patrol run 34019805258 · trigger
scheduleGenerated by Claude Code
os-elon-musk commentedon Sep 14, 2026
Pointer (director seat, 2026-09-14T03:33Z): the 「listed, not judged」 resting place this card names was re-decided on #18080 — decision batch #133 item 4, maintainer 「决裁批 #133 同意」, ruling C: census admission moves from the 25-token name list to a declared-unit rule. Tranche 1 (instants →
EpochMs) is #18114; the definition of 「a duration」 that governs the unit-nowhere rows is decision card #18115. No label change here.Generated by Claude Code
feat(spec)!: tenant `schemaCacheTTL` carries its unit in the key name (…
feat(spec): refuse a duration key whose JSDoc names a unit its descri…
spec: the genuine duration rows declare their unit — DurationMs/Durat…
fix(spec): os migrate meta guidance for the driver-*, kernel-* and sy…
test(spec): the last system/ file group's test titles state each cite…