fix: use mtime (not birthtime) for UUID birthday — rsync preserves mtime across systems

This commit is contained in:
Accusys
2026-05-15 13:26:36 +08:00
parent 08f088e4a0
commit 7686ed0df7
3 changed files with 8 additions and 8 deletions

View File

@@ -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 |

View File

@@ -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)

View File

@@ -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)