2.0.0 → 3.0.0, entry by entry
Ten BREAKING — entries, all from one bug sweep. Each was a documented surface that did nothing, or did the wrong thing; the fix is the edit named beside it. Full rationale per row in CHANGELOG.md's 3.0.0 section.
| Surface | The edit |
|---|---|
defineAuth({ mfa: { required: true } }) — refused at boot (X_CONFIG_INVALID), and AuthMfaPolicy.required narrowed to the literal false | delete mfa.required; enforce the requirement in your own enrolment flow. Nothing ever read the flag, so a user who never enrolled got a fully-privileged session under it |
enrolTotp(input) → enrolTotp(auth, input); input.issuer is now optional | pass the auth you built with defineAuth. The configured issuer never reached the otpauth:// URI before |
@ultimat3/http no longer exports appErrorStatus() | read your own registration module. registerErrorStatus() and statusFor() are unchanged |
SyncSocket.lastSeenAt → lastSeenMonotonicMs, on Clock.monotonic() | rename the read. If you were formatting it as a date you were already wrong — the rename makes new Date(...) a compile error |
SQL_OUTBOX_RELEASE and SQL_OUTBOX_MARK_PUBLISHED take one more parameter each (1 → 2, 2 → 3): the claimant | pass the claimant. OutboxStore.release/markPublished take it as an optional trailing argument, so an unfenced store still compiles |
SocketRegistry.sweepIdle() → idle(), which returns the over-budget sockets and removes nothing | call idle() and evict through the node, or set the budget with createSyncNode({ idleTimeoutMs }) |
DESCRIPTION_MIN_LENGTH deleted from @ultimat3/seo | delete the import. There is no replacement and no minimum description length is checked — the constant was documented as enforced and was read by no validator |
A metric redeclared with different bounds or a different observe is refused (X_METRIC_NAME_INVALID) | make the second declaration state the same bounds/observe, or fetch the handle without options — gauge(name) is unchanged |
Seed.run() resolves with SeedRun instead of void | re-type the result if you typed it void. Awaiting it for the side effect alone is unaffected |
SeedContext.insert skips a stored row instead of overwriting it | expect skipped, not an overwrite. upsert is the verb for a row the table keys |
cachedFormatter and canonicalLocale moved from @ultimat3/time to @ultimat3/core and are re-exported from time, so no import breaks — it is listed here because the move is real, not because it costs an edit.