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
sys_job.timezone and sys_report_schedule.timezone disagree with each other and neither is validated — the platform's own IANA columns predate valueDomain #15872
Found while implementing #14238 (maintainer ruling A: sys_business_unit.timezone and sys_organization.timezone, both text / optional / maxLength: 64 / valueDomain: 'iana_time_zone' / no default). Retrofitting the two older columns was explicitly outside that ruling's scope, so it is carded here rather than widened into that PR. Unassigned — for triage.
The reading
Measured on origin/main at 7b6825477, each file individually (a lane-wide grep for time_?zone returns 20+ hits and is not a reading about a file):
grep -c valueDomain in both files = 0. So the card #14238 was raised on — "every app invents the column differently" — is already true inside the platform's own objects, in three dimensions at once (length, default, validation), and since #14168 / #15161 the platform has the one declaration that closes the third dimension and these two columns do not carry it.
Consequence
A write of Mars/Olympus, UTC+8 or China Standard Time to either column is stored. Whatever reads the column at schedule time (service-job for sys_job, plugin-reports for sys_report_schedule) meets the bad value later, far from its cause. Not measured here: which reader consumes each column and what it does with a non-member (throws, falls back to UTC, or schedules at a wrong instant) — that is this card's first step, and it decides the severity.
Published surface (measured, Zone-1 rule)
Both columns are in the built packages/platform-objects/dist/audit/index.js / index.mjs (timezone ×2) and dist/audit/index.d.ts / index.d.mts (×3). content/docs/** mentions of either column's timezone: 0. So this is a published surface by the dist measurement, and a docs-absent one.
Proposed shape (for the implementing seat to verify, not a ruling)
Declare valueDomain: 'iana_time_zone' on both. It is the transition-gate class (min / max / maxLength): only a WRITTEN non-member is refused; stored values are never re-read, so no data migration and no ADR-0087 prescription.
Converge the bound on 64, the value No platform object carries a timezone, so every app that computes a date boundary has to invent one — and each will invent it differently #14238 chose and justified: the enumeration's longest name on the repo's Node baseline is 30 characters (America/Argentina/Rio_Gallegos), the longest tzdb link 32 (America/Argentina/ComodRivadavia), and the tzdb caps each path component at 14 — 64 is twice the domain's real ceiling. Narrowing 100 → 64 on sys_job needs the check-keyed-text-bounds family and a look at what the column physically holds.
The default is a consumer semantic (sys_report_schedule says UTC, sys_job says nothing); keep each as its reader expects unless the reader says otherwise.
Both objects are isSystem; the change widens a declared shape on a published package, so the changeset is at least minor and the review tier is a contract question for the PM, not for this card.
Re-check
git show origin/main:packages/platform-objects/src/audit/sys-job.object.ts | sed -n '64,69p'
git show origin/main:packages/platform-objects/src/audit/sys-report-schedule.object.ts | sed -n '81,87p'
git show origin/main:packages/platform-objects/src/audit/sys-job.object.ts | grep -c valueDomain # 0
git show origin/main:packages/platform-objects/src/audit/sys-report-schedule.object.ts | grep -c valueDomain # 0
Found while implementing #14238 (maintainer ruling A:
sys_business_unit.timezoneandsys_organization.timezone, bothtext/ optional /maxLength: 64/valueDomain: 'iana_time_zone'/ no default). Retrofitting the two older columns was explicitly outside that ruling's scope, so it is carded here rather than widened into that PR. Unassigned — for triage.The reading
Measured on
origin/mainat7b6825477, each file individually (a lane-wide grep fortime_?zonereturns 20+ hits and is not a reading about a file):valueDomainsys_job—packages/platform-objects/src/audit/sys-job.object.ts:64Field.text({ required: false, maxLength: 100 })sys_report_schedule—packages/platform-objects/src/audit/sys-report-schedule.object.ts:81Field.text({ required: false, maxLength: 64, defaultValue: 'UTC' })'UTC'grep -c valueDomainin both files = 0. So the card #14238 was raised on — "every app invents the column differently" — is already true inside the platform's own objects, in three dimensions at once (length, default, validation), and since #14168 / #15161 the platform has the one declaration that closes the third dimension and these two columns do not carry it.Consequence
A write of
Mars/Olympus,UTC+8orChina Standard Timeto either column is stored. Whatever reads the column at schedule time (service-job forsys_job, plugin-reports forsys_report_schedule) meets the bad value later, far from its cause. Not measured here: which reader consumes each column and what it does with a non-member (throws, falls back to UTC, or schedules at a wrong instant) — that is this card's first step, and it decides the severity.Published surface (measured, Zone-1 rule)
Both columns are in the built
packages/platform-objects/dist/audit/index.js/index.mjs(timezone×2) anddist/audit/index.d.ts/index.d.mts(×3).content/docs/**mentions of either column'stimezone: 0. So this is a published surface by the dist measurement, and a docs-absent one.Proposed shape (for the implementing seat to verify, not a ruling)
valueDomain: 'iana_time_zone'on both. It is the transition-gate class (min/max/maxLength): only a WRITTEN non-member is refused; stored values are never re-read, so no data migration and no ADR-0087 prescription.America/Argentina/Rio_Gallegos), the longest tzdb link 32 (America/Argentina/ComodRivadavia), and the tzdb caps each path component at 14 — 64 is twice the domain's real ceiling. Narrowing 100 → 64 onsys_jobneeds thecheck-keyed-text-boundsfamily and a look at what the column physically holds.sys_report_schedulesaysUTC,sys_jobsays nothing); keep each as its reader expects unless the reader says otherwise.Both objects are
isSystem; the change widens a declared shape on a published package, so the changeset is at leastminorand the review tier is a contract question for the PM, not for this card.Re-check