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
spec(gate): check-duration-unit-keys admits by DECLARATION (Duration*/EpochMs type or unit-in-name), the name list becomes a detector that refuses undeclared time-shaped numerics, dimensionless rows declare it in-schema — step ② of ruling A on #18115 #18123
Filed by the director seat (objectstack #12708, summon #23, session_01WCEaPsmKY4UyoivKkkaUHt) executing decision batch #134 item 1 — maintainer 「决裁批 #134 同意」 to A on #18115, 2026-09-14T03:44Z. Step ② of three: the census admission rule. domain:spec (the gate lives in packages/spec/scripts/); p2; pm:blocked until step ① (the types the gate must read) is on origin/main.
The ruling this card executes (verbatim from #18115, batch #134 item 1)
Dimensionless numbers declare that too, in the schema. The 17 rows the census classed dimensionless (11 counts, 5 backoffMultiplier, 1 instant that spec: route the 10 bare z.number() wall-clock instants to EpochMs (census #18078 class C ×4 + unit-nowhere instants ×6) — tranche 1 of ruling C on #18080 #18114 converts) are exempted by an in-schema marker the gate reads — the same mechanism as the existing externalVocabulary meta exemption (11 declared mirrors today) — ⛔ not a side ledger file (that was option B, not taken). Exact key name of the marker is the dev's (e.g. .meta({ unit: 'none' }) or dimensionless: true), chosen to sit beside externalVocabulary in the gate's own reader.
The 17 dimensionless rows all match the current 25-token list (that is how they entered the census) — so every one of them needs the marker in THIS PR or the new refusal reds on them. Apply the marker to all 17 here (they are schema edits with no runtime change), each with a one-line describe stating what the number counts.
(withdrawn with frame 2: there is no detector; rows the census did not draw are step ③'s to convert if they are genuine durations, or the schema author's to mark dimensionless when they next touch the key.)
Acceptance
--self-test exit 0 with new cases: (a) declared DurationMs key admitted and judged; (b) a bare z.number() whose name carries no unit is NOT judged and NOT refused (the name list is gone — assert DURATION_SHAPED_TOKENS no longer exists); (c) marked-dimensionless time-shaped key exempt; (d) EpochMs path unchanged; (e) a prose-only unit still does NOT admit (batch Add comprehensive test coverage for ObjectStack spec protocols - 100% coverage achieved #65 control).
--list baseline updated in the same PR; the summary line reports declared durations beside declared instants.
Before/after counts printed in the PR body: census rows, judged rows, dimensionless exemptions (expected 17); the genuine-duration rows step ③ converts are listed by name.
Clause-②: no — no published symbol moves (gate + schema meta only); changeset patch on @objectstack/spec if the meta markers touch published schemas (they do), else skip-changeset.
⛔ The genuine duration rows are NOT converted here — the refusal on them is expected red until step ③ lands; the PR body names them as the red step ③ clears. Land order: ① → ② and ③ in either order; if ② lands first the gate is red on main until ③ — ⛔ not acceptable: coordinate with ③'s dev so ② is enqueued only when ③ is ready to follow in the same queue window, or fold ② and ③ into one PR if the conversion population is ≤ 12 rows.
Fences
⛔ No key rename here; ⛔ no type definition here (step ①); ⛔ content/docs/releases/** untouched.
Re-check before claiming
git fetch origin main && cd packages/spec
tsx scripts/check-duration-unit-keys.ts --self-test # exit 0, note the case count
tsx scripts/check-duration-unit-keys.ts --list | tail -5 # the summary line, note `declared EpochMs instant(s)` count
git grep -n -E 'export const (DurationMs|DurationSeconds)' origin/main -- src # step ① landed? (must be ≥1 before this card is dispatchable)
Refs
#18115 (ruling A) · #18080 (ruling C) · #18078 (census — the 17 dimensionless rows are enumerated in its §A) · #14519 (unit-nowhere shape, superseded by this) · step ① / step ③ cards · packages/spec/scripts/check-duration-unit-keys.ts
Filed by the director seat (objectstack #12708, summon #23,
session_01WCEaPsmKY4UyoivKkkaUHt) executing decision batch #134 item 1 — maintainer 「决裁批 #134 同意」 to A on #18115, 2026-09-14T03:44Z. Step ② of three: the census admission rule.domain:spec(the gate lives inpackages/spec/scripts/); p2;pm:blockeduntil step ① (the types the gate must read) is onorigin/main.The ruling this card executes (verbatim from #18115, batch #134 item 1)
Ruling frame — ⛔ not re-adjudicable by the dev
Duration*/EpochMstype in its zod chain (identifier detection, exactly as the gate already countsdeclared EpochMs instant(s)today), or a unit token in its key name (the existingkeyUnitsreading). Prose (.describe()/ JSDoc) stays a consistency channel — it can contradict a declaration and be refused for it — ⛔ never an admission channel (batch Add comprehensive test coverage for ObjectStack spec protocols - 100% coverage achieved #65's declined direction, restated by spec: the option-1 population is measured — 6 rows, and it cannot reach the ≥7 duration keys that name no unit anywhere. What is the goal? #18080 ruling C).DURATION_SHAPED_TOKENSis deleted andisDurationShaped()'s name-shape reading stops existing; admission is by declaration only (aDuration*/EpochMstype, or a unit token in the key name viakeyUnits);--listno longer surfaces name-matched rows and the baseline shrinks accordingly. A barez.number()with no unit in its name and no duration type is not judged — the cost option A accepted. The ≥7 escaping genuine-duration rows are converted by step ③ (spec: the genuine duration rows adopt a declaration —DurationMs/DurationSecondsor a unit-suffixed name (census #18078 classes A-true ×6, B ×2, D ×≥2) — step ③ of ruling A on #18115 #18124), ⛔ not caught by any name rule.backoffMultiplier, 1 instant that spec: route the 10 barez.number()wall-clock instants toEpochMs(census #18078 class C ×4 + unit-nowhere instants ×6) — tranche 1 of ruling C on #18080 #18114 converts) are exempted by an in-schema marker the gate reads — the same mechanism as the existingexternalVocabularymeta exemption (11 declared mirrors today) — ⛔ not a side ledger file (that was option B, not taken). Exact key name of the marker is the dev's (e.g..meta({ unit: 'none' })ordimensionless: true), chosen to sit besideexternalVocabularyin the gate's own reader.PM mechanism assumptions — measure, falsify, report
scanTree/isDurationShaped/keyUnitsexports (census spec: measure the option-1 population batch #65 declined for being unmeasured — duration keys whose unit is named only in JSDoc, or nowhere at all (report-only census) #18078 used them) are the seams; identifier detection forEpochMsalready exists and generalises toDuration*by the same reader.Acceptance
--self-testexit 0 with new cases: (a) declaredDurationMskey admitted and judged; (b) a barez.number()whose name carries no unit is NOT judged and NOT refused (the name list is gone — assertDURATION_SHAPED_TOKENSno longer exists); (c) marked-dimensionless time-shaped key exempt; (d)EpochMspath unchanged; (e) a prose-only unit still does NOT admit (batch Add comprehensive test coverage for ObjectStack spec protocols - 100% coverage achieved #65 control).--listbaseline updated in the same PR; the summary line reports declared durations beside declared instants.Clause-②: no— no published symbol moves (gate + schema meta only); changesetpatchon@objectstack/specif the meta markers touch published schemas (they do), elseskip-changeset.mainuntil ③ — ⛔ not acceptable: coordinate with ③'s dev so ② is enqueued only when ③ is ready to follow in the same queue window, or fold ② and ③ into one PR if the conversion population is ≤ 12 rows.Fences
content/docs/releases/**untouched.Re-check before claiming
Refs
#18115 (ruling A) · #18080 (ruling C) · #18078 (census — the 17 dimensionless rows are enumerated in its §A) · #14519 (unit-nowhere shape, superseded by this) · step ① / step ③ cards ·
packages/spec/scripts/check-duration-unit-keys.tsDedup terms:
check-duration-unit-keys admission,isDurationShaped detector,dimensionless marker,declared unit channel,unit-nowhere refusalGenerated by Claude Code