fix: use mtime (not birthtime) for UUID birthday — rsync preserves mtime across systems
This commit is contained in:
@@ -23,8 +23,8 @@ status: "draft"
|
||||
|
||||
```
|
||||
SHA256 = DNA or fingerprint (immutable biometric identity)
|
||||
file created time = birth moment
|
||||
birthday (UUID anchor) = birth timestamp
|
||||
file mtime = birth moment (preserved by rsync across systems)
|
||||
birthday (UUID anchor) = mtime timestamp
|
||||
.pre.json = birth certificate
|
||||
POST /api/v1/files/register = civil registration
|
||||
status = registered = citizenship completed
|
||||
@@ -48,8 +48,8 @@ File watcher (`src/watcher/watcher.rs`) polls monitored directories every 60 sec
|
||||
### Computation Steps
|
||||
|
||||
```
|
||||
1. fs::metadata(path).created()
|
||||
→ birthday = file creation time (RFC 3339)
|
||||
1. fs::metadata(path).modified()
|
||||
→ birthday = file modification time (mtime, RFC 3339; preserved by rsync -a across systems)
|
||||
|
||||
2. SHA256(full file, streaming 64KB chunks)
|
||||
→ content_hash = 512-bit hex string (file DNA / fingerprint)
|
||||
@@ -94,7 +94,7 @@ Stored alongside other processor outputs:
|
||||
|
||||
### Key Design: UUID = f(mac, birthday, path, filename)
|
||||
|
||||
The `birthday` is `file created time` — obtained from `fs::metadata().created()`. This is the **true birth time** of the file, not the registration time.
|
||||
The `birthday` is `file modification time` (mtime) — obtained from `fs::metadata().modified()`. Using mtime instead of birthtime ensures UUID stability when files are transferred between systems via rsync (which preserves mtime but not birthtime on macOS).
|
||||
|
||||
```
|
||||
birthday = 2026-05-15T02:15:00Z ← file birth time, never changes
|
||||
@@ -144,7 +144,7 @@ curl -X POST http://localhost:3002/api/v1/files/register \
|
||||
|
||||
| Field | Source | Computed When | Mutable |
|
||||
|-------|--------|---------------|:------:|
|
||||
| `birthday` | `fs::metadata().created()` | Pre-process (once) | ❌ Never |
|
||||
| `birthday` | `fs::metadata().modified()` (mtime) | Pre-process (once) | ❌ Never (stable across rsync) |
|
||||
| `content_hash` (SHA256) | Full file | Pre-process (once) | ❌ Never (unless file modified) |
|
||||
| `file_uuid` | SHA256(mac\|birthday\|path\|filename) | Pre-process (once) | ❌ Never |
|
||||
| `registration_time` | `NOW()` at register | Register API | ✅ Per registration |
|
||||
|
||||
@@ -922,7 +922,7 @@ async fn register_single_file(
|
||||
|
||||
let birthday = std::fs::metadata(&path)
|
||||
.ok()
|
||||
.and_then(|m| m.created().ok())
|
||||
.and_then(|m| m.modified().ok())
|
||||
.map(|t| {
|
||||
let secs = t.duration_since(std::time::UNIX_EPOCH).unwrap_or_default().as_secs();
|
||||
chrono::DateTime::from_timestamp(secs as i64, 0)
|
||||
|
||||
@@ -93,7 +93,7 @@ pub async fn pre_process_file(file_path: &str) -> Option<String> {
|
||||
.unwrap_or_else(|_| "/Users/accusys/momentry/output_dev".to_string());
|
||||
|
||||
let birthday = std::fs::metadata(&path).ok()
|
||||
.and_then(|m| m.created().ok())
|
||||
.and_then(|m| m.modified().ok())
|
||||
.map(|t| {
|
||||
let secs = t.duration_since(std::time::UNIX_EPOCH).unwrap_or_default().as_secs();
|
||||
chrono::DateTime::from_timestamp(secs as i64, 0)
|
||||
|
||||
Reference in New Issue
Block a user