Found while documenting the metadata-lock bound for #9543 (docs PR #9608). Filed unassigned; not fixed in that PR — its declared file surface is content/docs/data-modeling/drivers.mdx, and packages/drivers/driver-sql/src/sql-driver.ts is outside it.
The observation
Boot schema sync's MySQL widening logs its swallowed failure at warn, on both twins (verified on origin/main @ ca2e020e4):
sql-driver.ts:8222 — this.logger.warn('[sql-driver] could not widen MySQL datetime columns on …; writes stay correct, but the 2038 ceiling and millisecond truncation remain')sql-driver.ts:8310 — this.logger.warn('[sql-driver] could not widen MySQL time columns on …; fractional-second writes keep rounding to whole seconds')
AGENTS.md's Degradation log levels section decides the level with one question:
After the degradation, does the system still look "normal" from the outside, while something it claims is persisted has not actually landed? Yes → error. No → warn/info is right.
and its error limb names this case in its own example list: "A write that claims to persist does not, DDL that was supposed to run did not, persisted state and runtime state disagree."
Both halves appear to hold here. After the swallow the platform boots, serves traffic and looks entirely normal; the DDL that was supposed to run did not; and the consequence the message itself states is silent — an un-widened TIMESTAMP truncates milliseconds, and an un-widened TIME rounds fractional seconds away, while datetime's documented canonical storage format promises milliseconds are always present. Nothing else reports that the widening is outstanding.
The counter-argument, stated fairly
runWideningAlters' own doc comment argues the opposite policy for the swallow, and that argument is sound: correctness never depended on the widening having run, a TIMESTAMP column keeps accepting and returning the same UTC instants, and a migration must never take boot down. Triage's 2026-08-18 auto-adjudication on #9542 deliberately kept boot's swallow.
But that reasoning is about throw vs swallow, not about warn vs error — and the level was never separately adjudicated: these two logger.warn calls predate both #9354 and #9542, which changed the wait and the escape around them without revisiting the level. Raising the level keeps the swallow intact and changes only whether the line is visible to an operator's log alerting, which is the only signal there is.
Note the level also governs how loud this gets now that the bound exists: before #9542, a blocked boot widening never returned, so this catch could not fire at all. It is newly reachable.
Not claimed here
Whether the maintainer's balance lands on error or on keeping warn is a judgment call about a documented convention, so this is filed for triage rather than fixed. If the answer is that warn is correct, the useful outcome is a sentence at the call sites saying why this one is exempt from the rule's DDL limb — right now nothing there addresses it, so the next reader re-derives the same question.
Related: #9354 and #9542 (the bound on each path) · #9543 / PR #9608 (the docs page that states the operator-visible consequence).
Generated by Claude Code
Found while documenting the metadata-lock bound for #9543 (docs PR #9608). Filed unassigned; not fixed in that PR — its declared file surface is
content/docs/data-modeling/drivers.mdx, andpackages/drivers/driver-sql/src/sql-driver.tsis outside it.The observation
Boot schema sync's MySQL widening logs its swallowed failure at
warn, on both twins (verified onorigin/main@ca2e020e4):sql-driver.ts:8222—this.logger.warn('[sql-driver] could not widen MySQL datetime columns on …; writes stay correct, but the 2038 ceiling and millisecond truncation remain')sql-driver.ts:8310—this.logger.warn('[sql-driver] could not widen MySQL time columns on …; fractional-second writes keep rounding to whole seconds')AGENTS.md's Degradation log levels section decides the level with one question:
and its
errorlimb names this case in its own example list: "A write that claims to persist does not, DDL that was supposed to run did not, persisted state and runtime state disagree."Both halves appear to hold here. After the swallow the platform boots, serves traffic and looks entirely normal; the DDL that was supposed to run did not; and the consequence the message itself states is silent — an un-widened
TIMESTAMPtruncates milliseconds, and an un-widenedTIMErounds fractional seconds away, whiledatetime's documented canonical storage format promises milliseconds are always present. Nothing else reports that the widening is outstanding.The counter-argument, stated fairly
runWideningAlters' own doc comment argues the opposite policy for the swallow, and that argument is sound: correctness never depended on the widening having run, aTIMESTAMPcolumn keeps accepting and returning the same UTC instants, and a migration must never take boot down. Triage's 2026-08-18 auto-adjudication on #9542 deliberately kept boot's swallow.But that reasoning is about throw vs swallow, not about
warnvserror— and the level was never separately adjudicated: these twologger.warncalls predate both #9354 and #9542, which changed the wait and the escape around them without revisiting the level. Raising the level keeps the swallow intact and changes only whether the line is visible to an operator's log alerting, which is the only signal there is.Note the level also governs how loud this gets now that the bound exists: before #9542, a blocked boot widening never returned, so this catch could not fire at all. It is newly reachable.
Not claimed here
Whether the maintainer's balance lands on
erroror on keepingwarnis a judgment call about a documented convention, so this is filed for triage rather than fixed. If the answer is thatwarnis correct, the useful outcome is a sentence at the call sites saying why this one is exempt from the rule's DDL limb — right now nothing there addresses it, so the next reader re-derives the same question.Related: #9354 and #9542 (the bound on each path) · #9543 / PR #9608 (the docs page that states the operator-visible consequence).
Generated by Claude Code