Skip to content

Commit e6f88f6

Browse files
authored
Merge pull request #7 from blacksky-algorithms/feature/community-and-peer-mod
feat: community posts, peer-mod, and actor badges
2 parents 01446eb + 6ac0811 commit e6f88f6

59 files changed

Lines changed: 2726 additions & 360 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"lexicon": 1,
3+
"id": "community.blacksky.actor.checkMembership",
4+
"defs": {
5+
"main": {
6+
"type": "query",
7+
"description": "Whether the calling account is a Blacksky community member.",
8+
"output": {
9+
"encoding": "application/json",
10+
"schema": {
11+
"type": "object",
12+
"required": ["isMember"],
13+
"properties": {
14+
"isMember": { "type": "boolean" }
15+
}
16+
}
17+
}
18+
}
19+
}
20+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"lexicon": 1,
3+
"id": "community.blacksky.badge.getBadges",
4+
"defs": {
5+
"main": {
6+
"type": "query",
7+
"description": "List an actor's active badges.",
8+
"parameters": {
9+
"type": "params",
10+
"required": ["actor"],
11+
"properties": {
12+
"actor": { "type": "string", "format": "did" }
13+
}
14+
},
15+
"output": {
16+
"encoding": "application/json",
17+
"schema": {
18+
"type": "object",
19+
"required": ["badges"],
20+
"properties": {
21+
"badges": {
22+
"type": "array",
23+
"items": { "type": "string" }
24+
}
25+
}
26+
}
27+
}
28+
}
29+
}
30+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"lexicon": 1,
3+
"id": "community.blacksky.badge.grantBadge",
4+
"defs": {
5+
"main": {
6+
"type": "procedure",
7+
"description": "Grant a badge to an actor. Admin only.",
8+
"input": {
9+
"encoding": "application/json",
10+
"schema": {
11+
"type": "object",
12+
"required": ["actor", "badge"],
13+
"properties": {
14+
"actor": { "type": "string", "format": "did" },
15+
"badge": { "type": "string", "maxLength": 64 }
16+
}
17+
}
18+
},
19+
"output": {
20+
"encoding": "application/json",
21+
"schema": {
22+
"type": "object",
23+
"required": ["granted"],
24+
"properties": {
25+
"granted": { "type": "boolean" }
26+
}
27+
}
28+
}
29+
}
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"lexicon": 1,
3+
"id": "community.blacksky.badge.revokeBadge",
4+
"defs": {
5+
"main": {
6+
"type": "procedure",
7+
"description": "Revoke a badge from an actor. Admin only.",
8+
"input": {
9+
"encoding": "application/json",
10+
"schema": {
11+
"type": "object",
12+
"required": ["actor", "badge"],
13+
"properties": {
14+
"actor": { "type": "string", "format": "did" },
15+
"badge": { "type": "string", "maxLength": 64 }
16+
}
17+
}
18+
},
19+
"output": {
20+
"encoding": "application/json",
21+
"schema": {
22+
"type": "object",
23+
"required": ["found"],
24+
"properties": {
25+
"found": { "type": "boolean" }
26+
}
27+
}
28+
}
29+
}
30+
}
31+
}

lexicons/community/blacksky/feed/post.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"defs": {
55
"main": {
66
"type": "record",
7-
"description": "Stub record for a Blacksky community post. Full content is stored on the Blacksky appview and hydrated for members only.",
7+
"description": "PDS-side stub for a Blacksky community post. The post's text, facets, langs, and reply chain are stored on the Blacksky appview and hydrated for members only. The optional `embed` field is mirrored onto the PDS stub so that the PDS's standard blob-retention pipeline (enumBlobRefs + record_blob bookkeeping) keeps any referenced blobs (image / video / external thumb / gallery / record-with-media) alive for the life of the record.",
88
"key": "tid",
99
"record": {
1010
"type": "object",
@@ -18,7 +18,18 @@
1818
"cid": {
1919
"type": "string",
2020
"format": "cid",
21-
"description": "CID of the full post content stored on the appview, for integrity verification."
21+
"description": "CID of the full post content stored on the appview, for integrity verification against the appview's canonical record."
22+
},
23+
"embed": {
24+
"type": "union",
25+
"refs": [
26+
"app.bsky.embed.images",
27+
"app.bsky.embed.video",
28+
"app.bsky.embed.gallery",
29+
"app.bsky.embed.external",
30+
"app.bsky.embed.record",
31+
"app.bsky.embed.recordWithMedia"
32+
]
2233
}
2334
}
2435
}

lexicons/community/blacksky/feed/submitPost.json

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
"encoding": "application/json",
1010
"schema": {
1111
"type": "object",
12-
"required": ["rkey", "text", "createdAt"],
12+
"required": [
13+
"rkey",
14+
"text",
15+
"createdAt"
16+
],
1317
"properties": {
1418
"rkey": {
1519
"type": "string",
@@ -24,9 +28,15 @@
2428
"facets": {
2529
"type": "array",
2630
"description": "Annotations of text (mentions, URLs, hashtags, etc)",
27-
"items": { "type": "ref", "ref": "app.bsky.richtext.facet" }
31+
"items": {
32+
"type": "ref",
33+
"ref": "app.bsky.richtext.facet"
34+
}
35+
},
36+
"reply": {
37+
"type": "ref",
38+
"ref": "#replyRef"
2839
},
29-
"reply": { "type": "ref", "ref": "#replyRef" },
3040
"embed": {
3141
"type": "union",
3242
"refs": [
@@ -41,18 +51,27 @@
4151
"type": "array",
4252
"description": "Indicates human language of post primary text content.",
4353
"maxLength": 3,
44-
"items": { "type": "string", "format": "language" }
54+
"items": {
55+
"type": "string",
56+
"format": "language"
57+
}
4558
},
4659
"labels": {
4760
"type": "union",
4861
"description": "Self-label values for this post.",
49-
"refs": ["com.atproto.label.defs#selfLabels"]
62+
"refs": [
63+
"com.atproto.label.defs#selfLabels"
64+
]
5065
},
5166
"tags": {
5267
"type": "array",
5368
"description": "Additional hashtags.",
5469
"maxLength": 8,
55-
"items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 }
70+
"items": {
71+
"type": "string",
72+
"maxLength": 640,
73+
"maxGraphemes": 64
74+
}
5675
},
5776
"createdAt": {
5877
"type": "string",
@@ -63,6 +82,31 @@
6382
"type": "string",
6483
"format": "cid",
6584
"description": "Client-computed CID for integrity verification. Server will reject if computed CID doesn't match."
85+
},
86+
"threadgateAllow": {
87+
"description": "Threadgate allow rules for a root post; omit for everyone, empty array for nobody.",
88+
"type": "array",
89+
"maxLength": 5,
90+
"items": {
91+
"type": "union",
92+
"refs": [
93+
"community.blacksky.feed.threadgate#mentionRule",
94+
"community.blacksky.feed.threadgate#followerRule",
95+
"community.blacksky.feed.threadgate#followingRule",
96+
"community.blacksky.feed.threadgate#listRule"
97+
]
98+
}
99+
},
100+
"embeddingRules": {
101+
"description": "Postgate embedding rules; a disableRule disables quote posts.",
102+
"type": "array",
103+
"maxLength": 5,
104+
"items": {
105+
"type": "union",
106+
"refs": [
107+
"community.blacksky.feed.postgate#disableRule"
108+
]
109+
}
66110
}
67111
}
68112
}
@@ -71,7 +115,9 @@
71115
"encoding": "application/json",
72116
"schema": {
73117
"type": "object",
74-
"required": ["uri"],
118+
"required": [
119+
"uri"
120+
],
75121
"properties": {
76122
"uri": {
77123
"type": "string",
@@ -102,11 +148,20 @@
102148
},
103149
"replyRef": {
104150
"type": "object",
105-
"required": ["root", "parent"],
151+
"required": [
152+
"root",
153+
"parent"
154+
],
106155
"properties": {
107-
"root": { "type": "ref", "ref": "com.atproto.repo.strongRef" },
108-
"parent": { "type": "ref", "ref": "com.atproto.repo.strongRef" }
156+
"root": {
157+
"type": "ref",
158+
"ref": "com.atproto.repo.strongRef"
159+
},
160+
"parent": {
161+
"type": "ref",
162+
"ref": "com.atproto.repo.strongRef"
163+
}
109164
}
110165
}
111166
}
112-
}
167+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"lexicon": 1,
3+
"id": "community.blacksky.moderation.applyLabel",
4+
"defs": {
5+
"main": {
6+
"type": "procedure",
7+
"description": "Apply a peer-moderation label to a community post.",
8+
"input": {
9+
"encoding": "application/json",
10+
"schema": {
11+
"type": "object",
12+
"required": ["subjectUri", "subjectCid", "val"],
13+
"properties": {
14+
"subjectUri": {
15+
"type": "string",
16+
"format": "at-uri",
17+
"description": "AT URI of the community post being labeled."
18+
},
19+
"subjectCid": {
20+
"type": "string",
21+
"format": "cid",
22+
"description": "CID of the community post version this label applies to."
23+
},
24+
"val": {
25+
"type": "string",
26+
"maxLength": 128,
27+
"description": "The label value (e.g. 'spam', 'harassment')."
28+
},
29+
"reason": {
30+
"type": "string",
31+
"maxLength": 2000,
32+
"description": "Optional explanation recorded with the Ozone event."
33+
}
34+
}
35+
}
36+
},
37+
"output": {
38+
"encoding": "application/json",
39+
"schema": {
40+
"type": "object",
41+
"required": ["val"],
42+
"properties": {
43+
"val": { "type": "string" },
44+
"subjectUri": { "type": "string", "format": "at-uri" }
45+
}
46+
}
47+
},
48+
"errors": [
49+
{
50+
"name": "PeerModRequired",
51+
"description": "The caller is not in the peer-moderator allowlist."
52+
},
53+
{
54+
"name": "InvalidSubject",
55+
"description": "Subject is not a community.blacksky.feed.post URI or does not exist."
56+
},
57+
{
58+
"name": "OzoneFailed",
59+
"description": "Ozone rejected the modEventLabel call; nothing was persisted."
60+
}
61+
]
62+
}
63+
}
64+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"lexicon": 1,
3+
"id": "community.blacksky.moderation.getMyLabels",
4+
"defs": {
5+
"main": {
6+
"type": "query",
7+
"description": "Return the label values the calling peer-moderator has applied to a given subject and not yet negated.",
8+
"parameters": {
9+
"type": "params",
10+
"required": ["subjectUri"],
11+
"properties": {
12+
"subjectUri": {
13+
"type": "string",
14+
"format": "at-uri"
15+
}
16+
}
17+
},
18+
"output": {
19+
"encoding": "application/json",
20+
"schema": {
21+
"type": "object",
22+
"required": ["vals"],
23+
"properties": {
24+
"vals": {
25+
"type": "array",
26+
"items": { "type": "string", "maxLength": 128 }
27+
}
28+
}
29+
}
30+
}
31+
}
32+
}
33+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"lexicon": 1,
3+
"id": "community.blacksky.moderation.getMyPermissions",
4+
"defs": {
5+
"main": {
6+
"type": "query",
7+
"description": "Report whether the calling user is a peer-moderator. Used by the client to gate the LabelDialog and Escalate-post affordances.",
8+
"output": {
9+
"encoding": "application/json",
10+
"schema": {
11+
"type": "object",
12+
"required": ["isPeerMod"],
13+
"properties": {
14+
"isPeerMod": { "type": "boolean" }
15+
}
16+
}
17+
}
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)