dev.atfs.file
Schema Diff
+15 -1
Compatibility Analysis
Backward Compatible
Backward compatible. 4 non-breaking changes.
Non-Breaking Changes (4)
- AddedVertex AddedVertex { vertex_id: "dev.atfs.file.tags" }
- AddedVertex AddedVertex { vertex_id: "dev.atfs.file.tags:items" }
- AddedEdge AddedEdge { src: "dev.atfs.file", tgt: "dev.atfs.file.tags", kind: "prop", name: Some("tags") }
- AddedEdge AddedEdge { src: "dev.atfs.file.tags", tgt: "dev.atfs.file.tags:items", kind: "items", name: None }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "dev.atfs.file.tags" }AddedVertex { vertex_id: "dev.atfs.file.tags:items" }
Additional Notes
- Non-breaking: AddedEdge { src: "dev.atfs.file", tgt: "dev.atfs.file.tags", kind: "prop", name: Some("tags") }
- Non-breaking: AddedEdge { src: "dev.atfs.file.tags", tgt: "dev.atfs.file.tags:items", kind: "items", name: None }
1
1
{
2
2
"id": "dev.atfs.file",
3
3
"defs": {
4
4
"main": {
5
5
"type": "object",
6
6
"required": [
7
7
"cid",
8
8
"ipfsRoot",
9
9
"size",
10
10
"mimeType"
11
11
],
12
12
"properties": {
13
13
"cid": {
14
14
"type": "cid-link",
15
15
"description": "The blessed CID of the file's bytes (CIDv1, raw multicodec, sha-256 multihash) — the canonical identity. This is what dev.atfs.repo.uploadFile (and its com.atproto.repo.uploadBlob alias) returns, what equality/dedup use, what atfs's own HTTP surfaces serve at any size, and the only DASL-compatible form. Never a DAG root."
16
16
},
17
17
"size": {
18
18
"type": "integer",
19
19
"description": "Size of the file, in bytes."
20
20
},
21
+
"tags": {
22
+
"type": "array",
23
+
"items": {
24
+
"type": "string",
25
+
"maxLength": 128,
26
+
"minLength": 1,
27
+
"description": "A single free-form tag: 1-128 bytes, no control characters. maxGraphemes is the same 128 rather than a smaller, byte-aware figure, because the bound atfs actually enforces is bytes, not graphemes — a tighter maxGraphemes here would advertise a stricter limit than the server applies.",
28
+
"maxGraphemes": 128
29
+
},
30
+
"maxLength": 16,
31
+
"minLength": 1,
32
+
"description": "Free-form labels attached to this content, deduplicated and sorted. Advisory and instance-local, in the same register as `providers`: never part of the file's identity (two identical uploads to two different instances, or under two different accounts, can carry entirely different tags for the same cid), never required for correctness, and not something a `dev.atfs.file` reference's recipient should trust as a global fact about the content — only as a note from whoever produced this reference. In dev.atfs.repo.listFiles output this is a union: every tag borne by ANY of that file's claims here — account-class and mirrored-server claims alike — with no indication of which claimant applied which; listFiles never discloses who pinned or tagged anything (pass listFiles' `did` parameter to scope this to one claimant's own tags instead). dev.atfs.repo.pinFile reads this field on input and adopts it verbatim under the calling instance's own claim (see dev.atfs.repo.pinFile)."
33
+
},
21
34
"ipfsRoot": {
22
35
"type": "cid-link",
23
36
"description": "The CID to fetch this file over the IPFS network: the UnixFS root for chunked (large) files, or exactly equal to `cid` when the file fits a single block. Always present, even when equal to `cid`, so consumers never need conditional logic — fetch `ipfsRoot`, then verify the bytes against `cid`. Chunker-dependent: this is *a* valid way to fetch the bytes, not a second identity — re-adding the same bytes elsewhere with different chunk settings would yield a different, equally valid root."
24
37
},
25
38
"mimeType": {
26
39
"type": "string",
27
40
"description": "The IANA media type of the file's bytes, exactly as recorded at upload time (see dev.atfs.repo.uploadFile). Defaults to application/octet-stream when the uploader supplied no Content-Type."
28
41
},
29
42
"providers": {
30
43
"type": "array",
31
44
"items": {
32
45
"type": "string",
33
46
"format": "uri"
34
47
},
48
+
"maxLength": 16,
35
49
"minLength": 1,
36
-
"description": "Advisory HTTPS origins (not full URLs — each is expected to answer both /ipfs/<cid> and a dev.atfs.repo.getFile-style XRPC, with the rest supplied by the author's DID), ordered by preference with the uploader's own instance first. Never required for correctness: a full IPFS client can always fall back to DHT routing."
50
+
"description": "Advisory HTTPS origins (not full URLs — each is expected to answer both /ipfs/<cid> and a dev.atfs.repo.getFile-style XRPC, with the rest supplied by the author's DID), ordered by preference with the uploader's own instance first. Never required for correctness: a full IPFS client can always fall back to DHT routing. HTTPS is meant literally — an atfs instance asked to pin this file skips any origin naming another scheme, and any origin resolving to an address that isn't routable on the public internet, since a providers list is a stranger's instruction about where to make connections."
37
51
}
38
52
}
39
53
}
40
54
},
41
55
"$type": "com.atproto.lexicon.schema",
42
56
"lexicon": 1,
43
57
"description": "An embeddable reference to a file hosted on an atfs instance and addressed by IPFS content-addressing. Deliberately not the native `blob` lexicon type: a PDS scans records for blob refs and rejects any whose blob isn't in its own blob store, which an atfs-hosted file structurally isn't. Embed this object in place of a blob field instead; field names (mimeType, size) are kept identical to blob refs for familiarity."
44
58
}