Files
mfer/mfer/mf.proto
T
clawbot e2deea2e34
check / check (push) Canceled after 0s
Drop mimeType and ctime from the manifest format (closes #235)
Nothing goes in the 1.0 manifest that 1.0 does not read or write, and
mfer never wrote either field. mf.proto now reserves the numbers 301 and
303 and both names in MFFilePath, and mf.pb.go is regenerated. The
decoded-size check counts only file entries, hashes and timestamps, and
counts a file entry, 16 bytes smaller without the two fields, at 160
bytes. export prints no ctime, and FileEntry loses the Ctime nothing
set. FORMAT.md and the README no longer describe either field.

The test of entries that decode too large gives each entry a second,
empty hash: an entry with one hash and a modification time can no
longer reach 8 times its size.

Model: opus-5-5
2026-10-19 20:52:00 +02:00

94 lines
2.5 KiB
Protocol Buffer

syntax = "proto3";
option go_package = "sneak.berlin/go/mfer/mfer";
message Timestamp {
int64 seconds = 1;
int32 nanos = 2;
}
message MFFileOuter {
enum Version {
VERSION_NONE = 0;
VERSION_ONE = 1; // only one for now
}
// required mffile root attributes 1xx
Version version = 101;
enum CompressionType {
COMPRESSION_NONE = 0;
COMPRESSION_ZSTD = 1;
}
CompressionType compressionType = 102;
// these are used solely to detect corruption/truncation
// and not for cryptographic integrity.
int64 size = 103;
bytes sha256 = 104;
// uuid must match the uuid in the inner message
bytes uuid = 105;
bytes innerMessage = 199;
// 2xx for optional manifest root attributes
// one OpenPGP signature, armored or binary, over the canonical string
// ZNAVSRFG-<uuid>-<sha256 as a multihash>, with the uuid as 32
// lower-case hex digits and no hyphens, and the multihash in lower-case
// hex (see docs/FORMAT.md). A signature is never stored anywhere else.
optional bytes signature = 201;
// fingerprint of the signing primary key, in upper-case hex
optional bytes signer = 202;
// OpenPGP public key of the signer, one primary key, armored or binary
optional bytes signingPubKey = 203;
}
message MFFilePath {
// required attributes:
// Path invariants: must be valid UTF-8, use forward slashes only,
// be relative (no leading /), contain no ".." or "." segments, and
// no empty segments (no "//").
string path = 1;
int64 size = 2;
// gotta have at least one:
repeated MFFileChecksum hashes = 3;
// optional per-file metadata
optional Timestamp mtime = 302;
// permission bits, at most 0777; 0 when not recorded
uint32 mode = 304;
// used by no field, so that a later version cannot reuse them by accident
reserved 301, 303;
reserved "mimeType", "ctime";
}
message MFFileChecksum {
// 1.0 golang implementation must write a multihash here
// it's ok to only ever use/verify sha256 multihash
bytes multiHash = 1;
}
message MFFile {
enum Version {
VERSION_NONE = 0;
VERSION_ONE = 1; // only one for now
}
Version version = 100;
// required manifest attributes:
repeated MFFilePath files = 101;
// uuid is a random v4 UUID generated when creating the manifest
// used as part of the signature to prevent replay attacks
bytes uuid = 102;
// optional manifest attributes 2xx:
optional Timestamp createdAt = 201;
}