net.anisota.graph.wordlist

anisota.net

Schema Diff

+10 -1

From

CID
bafyreidfu5yh2qt...
Indexed At
2026-07-26 20:11 UTC
View this version

To

CID
bafyreifnqe2ermf...
Indexed At
2026-08-07 01:42 UTC
View this version

Compatibility Analysis

Backward Compatible

Backward compatible. 2 non-breaking changes.

Non-Breaking Changes (2)
  • AddedVertex AddedVertex { vertex_id: "net.anisota.graph.wordlist:body.treatment" }
  • AddedEdge AddedEdge { src: "net.anisota.graph.wordlist:body", tgt: "net.anisota.graph.wordlist:body.treatment", kind: "prop", name: Some("treatment") }

Migration Guidance

Added Elements

  • AddedVertex { vertex_id: "net.anisota.graph.wordlist:body.treatment" }

Additional Notes

  • Non-breaking: AddedEdge { src: "net.anisota.graph.wordlist:body", tgt: "net.anisota.graph.wordlist:body.treatment", kind: "prop", name: Some("treatment") }
1 1
{
2 2
  "id": "net.anisota.graph.wordlist",
3 3
  "defs": {
4 4
    "main": {
5 5
      "key": "tid",
6 6
      "type": "record",
7 7
      "record": {
8 8
        "type": "object",
9 9
        "required": [
10 10
          "name",
11 11
          "words",
12 12
          "createdAt"
13 13
        ],
14 14
        "properties": {
15 15
          "name": {
16 16
            "type": "string",
17 17
            "maxLength": 64,
18 18
            "description": "Display name for this word list"
19 19
          },
20 20
          "words": {
21 21
            "type": "array",
22 22
            "items": {
23 23
              "ref": "#word",
24 24
              "type": "ref"
25 25
            },
26 26
            "maxLength": 500,
27 27
            "description": "The muted words/phrases in this list"
28 28
          },
29 29
          "source": {
30 30
            "ref": "#source",
31 31
            "type": "ref"
32 32
          },
33 33
          "enabled": {
34 34
            "type": "boolean",
35 35
            "default": false,
36 36
            "description": "Whether this list is currently active. Scheduling and spell effects further gate an enabled list."
37 37
          },
38 38
          "schedule": {
39 39
            "ref": "#schedule",
40 40
            "type": "ref",
41 41
            "description": "Optional active window. Absent means the list applies at all times while enabled."
42 42
          },
43 43
          "strength": {
44 44
            "type": "integer",
45 45
            "maximum": 100,
46 46
            "minimum": 0,
47 -
            "description": "Mute strength percentage: the share of matching posts this list mutes (deterministic per post). Absent means 100 (mute everything it matches)."
47 +
            "description": "Mute strength percentage: the share of matching posts this list mutes. Which posts fill that share is decided by match confidence — how many of the list's words hit, whether they landed in the post's own text, a hashtag, or only a quoted post, and how much of the post they account for — so a softened list keeps the squarest matches muted and lets the marginal ones through. Deterministic per post, so a post never flickers. Absent means 100 (mute everything it matches)."
48 48
          },
49 49
          "createdAt": {
50 50
            "type": "string",
51 51
            "format": "datetime",
52 52
            "description": "When this list was created"
53 53
          },
54 +
          "treatment": {
55 +
            "type": "string",
56 +
            "description": "What this list does to a post it mutes, overriding the app-wide muted-words handling: 'hide' removes it from feeds, 'warn' collapses it behind a notice, 'show' leaves it visible and only counts it toward impact. Absent inherits the global setting.",
57 +
            "knownValues": [
58 +
              "hide",
59 +
              "warn",
60 +
              "show"
61 +
            ]
62 +
          },
54 63
          "updatedAt": {
55 64
            "type": "string",
56 65
            "format": "datetime",
57 66
            "description": "When this list was last modified"
58 67
          },
59 68
          "description": {
60 69
            "type": "string",
61 70
            "maxLength": 300,
62 71
            "description": "Optional description of what this list covers"
63 72
          },
64 73
          "targetFeeds": {
65 74
            "type": "array",
66 75
            "items": {
67 76
              "type": "string",
68 77
              "maxLength": 512
69 78
            },
70 79
            "maxLength": 50,
71 80
            "description": "Feeds where this list applies: feed generator / list at-uris, or the literal sentinel 'following' for the home timeline. Empty or absent applies everywhere."
72 81
          },
73 82
          "syncToBluesky": {
74 83
            "type": "boolean",
75 84
            "default": false,
76 85
            "description": "Whether this list's words are also projected into Bluesky's native mutedWordsPref (managed entries, removed when the list is disabled or deleted)."
77 86
          }
78 87
        }
79 88
      },
80 89
      "description": "A named, shareable list of muted words/phrases — Anisota's managed layer on top of Bluesky's flat muted-words preference. Each list is a complete, self-contained record so it can be shared by URL and saved (copied) into another user's PDS, mirroring the net.anisota.spell.custom architecture. Muting is applied client-side by the moderation pipeline: multiple enabled lists combine, a list can be scoped to specific feeds, restricted to a time-of-day/day-of-week window, and softened with a strength percentage (mute only that share of matching posts, deterministically per post). A list can optionally be projected into Bluesky's native mutedWordsPref for parity with other clients."
81 90
    },
82 91
    "word": {
83 92
      "type": "object",
84 93
      "required": [
85 94
        "value"
86 95
      ],
87 96
      "properties": {
88 97
        "value": {
89 98
          "type": "string",
90 99
          "maxLength": 100,
91 100
          "description": "The word or phrase to mute"
92 101
        },
93 102
        "targets": {
94 103
          "type": "array",
95 104
          "items": {
96 105
            "type": "string",
97 106
            "knownValues": [
98 107
              "content",
99 108
              "tag"
100 109
            ]
101 110
          },
102 111
          "description": "What to match against: post text ('content') and/or hashtags ('tag'). Absent means both."
103 112
        },
104 113
        "actorTarget": {
105 114
          "type": "string",
106 115
          "description": "Whose posts to apply this word to. Absent means 'all'.",
107 116
          "knownValues": [
108 117
            "all",
109 118
            "exclude-following"
110 119
          ]
111 120
        }
112 121
      },
113 122
      "description": "One muted word or phrase, matching the shape of Bluesky's mutedWord items so a list can be projected into the native preference losslessly."
114 123
    },
115 124
    "source": {
116 125
      "type": "object",
117 126
      "properties": {
118 127
        "type": {
119 128
          "type": "string",
120 129
          "knownValues": [
121 130
            "original",
122 131
            "learned"
123 132
          ]
124 133
        },
125 134
        "rootDid": {
126 135
          "type": "string",
127 136
          "format": "did",
128 137
          "description": "DID of the original author at the top of the lineage."
129 138
        },
130 139
        "rootUri": {
131 140
          "type": "string",
132 141
          "format": "at-uri",
133 142
          "description": "AT URI of the first author's list — the top of the lineage — propagated to every descendant."
134 143
        },
135 144
        "originalDid": {
136 145
          "type": "string",
137 146
          "format": "did",
138 147
          "description": "DID of the user this list was saved from."
139 148
        },
140 149
        "originalUri": {
141 150
          "type": "string",
142 151
          "format": "at-uri",
143 152
          "description": "AT URI of the list this copy was saved from (its immediate parent)."
144 153
        }
145 154
      },
146 155
      "description": "Provenance. An 'original' list was created here; a 'learned' list was saved from another user, carrying a backlink to its immediate parent (originalUri/originalDid) and to the top of its lineage (rootUri/rootDid), modelled on net.anisota.spell.custom so save counts can aggregate across re-shares."
147 156
    },
148 157
    "schedule": {
149 158
      "type": "object",
150 159
      "properties": {
151 160
        "days": {
152 161
          "type": "array",
153 162
          "items": {
154 163
            "type": "integer",
155 164
            "maximum": 6,
156 165
            "minimum": 0
157 166
          },
158 167
          "maxLength": 7,
159 168
          "description": "Days of week the list is active (0 = Sunday … 6 = Saturday)"
160 169
        },
161 170
        "endTime": {
162 171
          "type": "string",
163 172
          "maxLength": 5,
164 173
          "description": "Window end as 'HH:MM' local time"
165 174
        },
166 175
        "startTime": {
167 176
          "type": "string",
168 177
          "maxLength": 5,
169 178
          "description": "Window start as 'HH:MM' local time"
170 179
        }
171 180
      },
172 181
      "description": "A recurring active window. Days and time window combine: the list applies only on the listed days (absent/empty = every day) and only inside the time window (absent = all day). A window whose end is at or before its start wraps past midnight."
173 182
    }
174 183
  },
175 184
  "$type": "com.atproto.lexicon.schema",
176 185
  "lexicon": 1
177 186
}

Compare Other Versions

Lexicon Garden

@