Measured while implementing #14037. That card listed this site as a lower-confidence neighbour it could not resolve, and its triage ruled it explicitly out of scope with "file a separate card if it turns out to be real". It is real, and the declaration the neighbour note could not locate is named below. #14037 does not address it.
The site
packages/metadata-protocol/src/sys-metadata-repository.ts, in listDrafts, measured on origin/main at 431979e67:
1140 updatedAt: row.updated_at ?? row.created_at ?? null,
The declaration the #14037 note could not find
It is not a Zod schema — which is exactly why a schema search came up empty. It is an inline TypeScript return type on the method itself, in the same file:
1108 updatedAt: string | null;
(inside listDrafts's Promise<Array<{ type: string; name: string; organizationId: string | null; packageId: string | null; updatedAt: string | null; updatedBy: string | null }>>)
So the declared type is string | null, and rows is cast as any[] one line above the map, which is why tsc reports nothing. The ?? chain fires only on nullish, so a Date walks straight past it into the declared field.
Why the value is a Date on the live dialects
updated_at / created_at are BUILTIN audit columns. SqlDriver#formatOutput repairs them (repairNaiveUtcAuditTimestamp) only inside its if (this.isSqlite) arm, and withPostgresCalendarDayAsText leaves timestamptz / timestamp deliberately untouched because those are instants. Pinned live in packages/drivers/driver-sql/src/sql-driver-13567-audit-stamp-materialisation.test.ts.
Severity, stated rather than assumed
Lower than #14037's three z.string().datetime() fields: this declaration is a plain string | null with no runtime refinement anywhere on the path, so there is no armed .parse() to trip. What it does today is hand a Date to a consumer whose type says string — the Studio "pending changes" list is the named consumer of this projection.
Suggested shape, not a decision
The same producer-side route #13997 and #14037 took: canonicalise at the adapter boundary that asserts the declared type. Two standing prohibitions from #13973 apply unchanged: no tolerant ?? fallback in a consumer, and no normalisation at the driver's read door.
One constraint worth carrying into whoever picks this up: the shared canonical-ISO spelling raises RangeError: Invalid time value on an Invalid Date, which #14078 measured to be reachable on both live dialects and which #13973 is blocked on. #14037 handled that by converting only a valid Date and passing every other shape through unchanged, so the fix imported neither answer to #14078; the same posture is available here.
Backlinks: #14037 (where this was measured, and which does not address it), #13973 (the census), #13997, #14078. None of them are addressed here.
Generated by Claude Code
Measured while implementing #14037. That card listed this site as a lower-confidence neighbour it could not resolve, and its triage ruled it explicitly out of scope with "file a separate card if it turns out to be real". It is real, and the declaration the neighbour note could not locate is named below. #14037 does not address it.
The site
packages/metadata-protocol/src/sys-metadata-repository.ts, inlistDrafts, measured onorigin/mainat431979e67:The declaration the #14037 note could not find
It is not a Zod schema — which is exactly why a schema search came up empty. It is an inline TypeScript return type on the method itself, in the same file:
(inside
listDrafts'sPromise<Array<{ type: string; name: string; organizationId: string | null; packageId: string | null; updatedAt: string | null; updatedBy: string | null }>>)So the declared type is
string | null, androwsis castas any[]one line above the map, which is why tsc reports nothing. The??chain fires only on nullish, so aDatewalks straight past it into the declared field.Why the value is a
Dateon the live dialectsupdated_at/created_atare BUILTIN audit columns.SqlDriver#formatOutputrepairs them (repairNaiveUtcAuditTimestamp) only inside itsif (this.isSqlite)arm, andwithPostgresCalendarDayAsTextleavestimestamptz/timestampdeliberately untouched because those are instants. Pinned live inpackages/drivers/driver-sql/src/sql-driver-13567-audit-stamp-materialisation.test.ts.Severity, stated rather than assumed
Lower than #14037's three
z.string().datetime()fields: this declaration is a plainstring | nullwith no runtime refinement anywhere on the path, so there is no armed.parse()to trip. What it does today is hand aDateto a consumer whose type saysstring— the Studio "pending changes" list is the named consumer of this projection.Suggested shape, not a decision
The same producer-side route #13997 and #14037 took: canonicalise at the adapter boundary that asserts the declared type. Two standing prohibitions from #13973 apply unchanged: no tolerant
??fallback in a consumer, and no normalisation at the driver's read door.One constraint worth carrying into whoever picks this up: the shared canonical-ISO spelling raises
RangeError: Invalid time valueon an InvalidDate, which #14078 measured to be reachable on both live dialects and which #13973 is blocked on. #14037 handled that by converting only a validDateand passing every other shape through unchanged, so the fix imported neither answer to #14078; the same posture is available here.Backlinks: #14037 (where this was measured, and which does not address it), #13973 (the census), #13997, #14078. None of them are addressed here.
Generated by Claude Code