Add microsecond manifest timestamps #16

Merged
erik merged 6 commits from bug/microsecond-timestamps into main 2026-06-25 04:23:40 +00:00
Member

Refs: #9


Summary

  • Encode manifest and tombstone created_at values as fixed-width UTC microsecond timestamps.
  • Preserve walker mtimes to microsecond precision and persist them as RFC3339Nano strings.
  • Replace manifest timestamp regex validation with RFC3339Nano parsing plus a literal Z suffix check.
  • Update schemas, fixtures, tests, and wiki notes for the new timestamp precision.

Validation

  • just check
  • GOTOOLCHAIN=go1.26.4+auto just validate

Note: plain just validate failed on the host go1.26.3 standard-library vulnerabilities reported by govulncheck; rerunning with the fixed go1.26.4 toolchain passed.

Refs: #9 --- ## Summary - Encode manifest and tombstone `created_at` values as fixed-width UTC microsecond timestamps. - Preserve walker mtimes to microsecond precision and persist them as RFC3339Nano strings. - Replace manifest timestamp regex validation with RFC3339Nano parsing plus a literal `Z` suffix check. - Update schemas, fixtures, tests, and wiki notes for the new timestamp precision. ## Validation - `just check` - `GOTOOLCHAIN=go1.26.4+auto just validate` Note: plain `just validate` failed on the host `go1.26.3` standard-library vulnerabilities reported by `govulncheck`; rerunning with the fixed `go1.26.4` toolchain passed.
Add microsecond manifest timestamps
All checks were successful
Validate / validate (pull_request) Successful in 1m47s
effb8fefb4
Use canonical mtimes in manifest fixtures
Some checks failed
Validate / validate (pull_request) Failing after 32s
668c7d8d2f
Reject non-canonical typed manifest timestamps
Some checks failed
Validate / validate (pull_request) Failing after 33s
53aadb4794
Entry mtimes were produced with time.RFC3339Nano, which trims trailing zeros (and drops the fraction entirely on a whole-second boundary), while the validator added in e9aa56c requires the fixed-width manifestTimeLayout with six fractional digits. The two disagree whenever a file's microsecond fraction has trailing zeros, so a peer rejects the manifest at decode and never applies the entry.

This surfaced as TestIntegrationTombstonePropagation passing locally (APFS nanosecond mtimes almost always fill six digits) but failing on CI, whose temp filesystem coarsens mtimes to whole seconds — fraction zero, RFC3339Nano emits "…:00Z", validator wants "…:00.000000Z", reject every time.

Add manifest.CanonicalTime as the single canonical formatter and use it on both producers (fswalk run/classify) so producer and validator share one source of truth. Regression test writes a file with a whole-second mtime and drives the full encode→DecodeManifest path a peer takes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pin lint toolchain to the module go directive
All checks were successful
Validate / validate (pull_request) Successful in 48s
66ceae105a
golangci-lint embeds a typechecker built against a specific Go release, and GOTOOLCHAIN=auto lets a newer locally-installed Go drift ahead so the linter panics on stdlib it can't parse (seen locally with Go 1.26 against a 1.25-built golangci-lint). Pin GOTOOLCHAIN for the lint recipe to the version in go.mod's go directive so local matches CI regardless of installed Go; reading it from go.mod means a future go bump moves it automatically. Bump golangci-lint in lockstep when bumping Go.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
erik merged commit ae57cb0872 into main 2026-06-25 04:23:40 +00:00
erik deleted branch bug/microsecond-timestamps 2026-06-25 04:23:40 +00:00
Sign in to join this conversation.
No description provided.