Background
TorExitNode.updated_at and TrustedUserAgent.updated_at are currently stored as chrono string bytes. Changing these values to Jiff-native strings, Jiff default serde, or primitive timestamp bytes changes the stored contract and should be handled as explicit data migration.
Since these surfaces already require migration, the new stored contract should use i64 epoch seconds instead of another library-dependent string format. This follows the existing metadata timestamp convention more closely than i64 nanoseconds: event keys, event fields, column_stats, and time_series use nanoseconds where precise event ordering/search matters, while metadata-style timestamps such as ModelIndicator.last_modification_time already use a seconds contract. These updated_at values are metadata refresh timestamps rather than event-ordering keys, so seconds precision is the intended new contract.
Prerequisites
- String timestamp baseline has landed.
Scope
- Migrate
TorExitNode.updated_at to i64 epoch seconds stored bytes.
- Migrate
TrustedUserAgent.updated_at to i64 epoch seconds stored bytes.
- Implement data migration from old chrono string bytes to the new stored schema.
- Keep old stored schemas as migration structures following existing migration conventions.
- Add migration tests that exercise the production migration path.
Acceptance criteria
- The issue or PR documents
i64 epoch seconds as the chosen new stored contract.
- The issue or PR explicitly states that subsecond precision from old string values is not preserved because these fields are metadata refresh timestamps.
- Old chrono string bytes for
TorExitNode.updated_at migrate successfully.
- Old chrono string bytes for
TrustedUserAgent.updated_at migrate successfully.
- Migration succeeds on an empty DB.
- Migration succeeds on an old DB fixture.
- Re-running migration after completion is a successful no-op.
- Resulting state is consistent, including data and backup VERSION files.
review-migrate is used for coverage where practical.
- The production read path is not required to permanently dual-read old chrono string bytes after migration.
Out of scope
- Backward-write compatibility where an old binary reads a DB written by the new code.
- Migrating unrelated table values.
- Final chrono dependency cleanup.
Notes
Related discussion: #733
Background
TorExitNode.updated_atandTrustedUserAgent.updated_atare currently stored as chrono string bytes. Changing these values to Jiff-native strings, Jiff default serde, or primitive timestamp bytes changes the stored contract and should be handled as explicit data migration.Since these surfaces already require migration, the new stored contract should use
i64epoch seconds instead of another library-dependent string format. This follows the existing metadata timestamp convention more closely thani64nanoseconds: event keys, event fields,column_stats, andtime_seriesuse nanoseconds where precise event ordering/search matters, while metadata-style timestamps such asModelIndicator.last_modification_timealready use a seconds contract. Theseupdated_atvalues are metadata refresh timestamps rather than event-ordering keys, so seconds precision is the intended new contract.Prerequisites
Scope
TorExitNode.updated_attoi64epoch seconds stored bytes.TrustedUserAgent.updated_attoi64epoch seconds stored bytes.Acceptance criteria
i64epoch seconds as the chosen new stored contract.TorExitNode.updated_atmigrate successfully.TrustedUserAgent.updated_atmigrate successfully.review-migrateis used for coverage where practical.Out of scope
Notes
Related discussion: #733