From 343431dd30eccf45e2cb0b5c5c40c1549e552fab Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Tue, 6 Oct 2026 03:26:16 +0200 Subject: [PATCH] Drop atime from the format spec and pin the file entry fields (closes #158) atime left mf.proto earlier and nothing reads or writes it, but docs/FORMAT.md still narrated its removal and listed it among the determinism rules. The spec now describes the file entry by its fields only. A new test compares the MFFilePath message descriptor, by name and number, with a list copied from the spec's field table. It does not read the spec, so changing a field means changing the proto, the spec and that list together. Model: opus-5-5 --- docs/FORMAT.md | 4 ---- mfer/mf_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/FORMAT.md b/docs/FORMAT.md index 6ff067c..44e8e7c 100644 --- a/docs/FORMAT.md +++ b/docs/FORMAT.md @@ -78,9 +78,6 @@ Each file entry contains: | `mtime` | 302 | Timestamp (optional) | Modification time | | `ctime` | 303 | Timestamp (optional) | Change time (inode metadata change) | -Field 304 (`atime`) has been removed from the specification. Access time is -volatile and non-deterministic; it is not useful for integrity verification. - ## Path Rules All `path` values must satisfy these invariants: @@ -130,7 +127,6 @@ By default, manifests are generated deterministically: - File entries are sorted by `path` in **lexicographic byte order** - `createdAt` is omitted unless explicitly requested -- `atime` is never included (field removed from schema) This ensures that two independent runs over the same directory tree produce byte-identical `.mf` files (assuming file contents and metadata have not diff --git a/mfer/mf_test.go b/mfer/mf_test.go index f481176..489f411 100644 --- a/mfer/mf_test.go +++ b/mfer/mf_test.go @@ -8,6 +8,8 @@ import ( "testing" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/reflect/protoreflect" + "sneak.berlin/go/mfer/mfer" ) // mf.pb.go is generated from mf.proto and committed. `make generate` @@ -27,3 +29,26 @@ func TestGeneratedCodeMatchesProto(t *testing.T) { "mfer/mf.proto has changed since mfer/mf.pb.go was generated "+ "from it: run `make generate` and commit the result") } + +// A file entry has exactly the fields docs/FORMAT.md lists for MFFilePath. +func TestFileEntryFieldsMatchSpec(t *testing.T) { + t.Parallel() + + want := map[string]protoreflect.FieldNumber{ + "path": 1, + "size": 2, + "hashes": 3, + "mimeType": 301, + "mtime": 302, + "ctime": 303, + } + + got := map[string]protoreflect.FieldNumber{} + + fields := (&mfer.MFFilePath{}).ProtoReflect().Descriptor().Fields() + for i := range fields.Len() { + got[string(fields.Get(i).Name())] = fields.Get(i).Number() + } + + require.Equal(t, want, got) +}