From
bafyreicqzpsgg4qtaphkp5il6fufn4mtpfq4elhgqqydckppynzk5rc6k4
indexed 2026-09-21 04:07 UTC
View this version
To
bafyreiewccccxff7jn4ei4nmx5digmvgfzzcvn3mqlvucoahh2kd7tugri
indexed 2026-10-10 22:06 UTC
View this version
Compatibility
backward compatible Backward compatible. 2 non-breaking changes.
Non-breaking changes (2)
- AddedVertex AddedVertex { vertex_id: "town.chalky.task:body.rank" }
- AddedEdge AddedEdge { src: "town.chalky.task:body", tgt: "town.chalky.task:body.rank", kind: "prop", name: Some("rank") }
Migration guidance
Added
AddedVertex { vertex_id: "town.chalky.task:body.rank" }
Notes
- Non-breaking: AddedEdge { src: "town.chalky.task:body", tgt: "town.chalky.task:body.rank", kind: "prop", name: Some("rank") }
Changes
11
{22
"$type": "com.atproto.lexicon.schema",33
"defs": {44
"main": {55
"description": "A single task in a chalky.town weekly planner. Stored in the author's repo. Field names mirror app.attodo.task where the concept is shared (title/description/completed/completedAt and the rec* recurrence fields); chalky-specific fields (day, order, color, subtasks, updatedAt) extend it. A recurring task is a template that projects occurrences onto later matching days; per-occurrence state (done/skipped) lives in separate town.chalky.occurrence records that reference this one.",66
"key": "tid",77
"record": {88
"properties": {99
"color": {1010
"description": "Id of a color in the author's editable palette (town.chalky.config#colors). knownValues lists the five built-in defaults; any other palette color id is also valid since the field is open.",1111
"knownValues": [1212
"salmon",1313
"chardonnay",1414
"witch-haze",1515
"mint-green",1616
"melrose"1717
],1818
"type": "string"1919
},2020
"completed": {2121
"default": false,2222
"type": "boolean"2323
},2424
"completedAt": {2525
"description": "When `completed` last flipped to true (non-recurring tasks only; recurring tasks track per-occurrence completion in completedDates).",2626
"format": "datetime",2727
"type": "string"2828
},2929
"createdAt": {3030
"format": "datetime",3131
"type": "string"3232
},3333
"day": {3434
"description": "Local calendar day the task sits on, as YYYY-MM-DD. Omit for the Someday bucket.",3535
"type": "string"3636
},3737
"description": {3838
"description": "Optional longer notes. May contain block-level Markdown (headings, lists, links, code, etc.); clients that don't render Markdown can show it as plain text.",3939
"maxLength": 3000,4040
"type": "string"4141
},4242
"isRecurring": {4343
"default": false,4444
"description": "Whether this task is a recurring template.",4545
"type": "boolean"4646
},4747
"movedAt": {48
"description": "When movedRank was last set.",48
"description": "When rank (or, on a legacy record, movedRank) was last set.",4949
"format": "datetime",5050
"type": "string"5151
},5252
"movedRank": {53
"description": "The malleable sort strategy's pinned position, on the same numeric axis as color rank. Set when the user drags this task while that strategy is active; cleared when its color changes, rejoining the color grouping.",53
"description": "Legacy, read-only: the malleable sort strategy's pinned position on the small unscaled color-rank axis, written by clients built before `rank` existed. Current clients read this (scaled up) only when `rank` is absent, and never write it — write `rank` instead.",5454
"type": "integer"5555
},5656
"order": {57
"description": "Fractional-ish sort key within a day; lower sorts higher.",57
"description": "Sort key within a day; lower sorts higher. Integer, atproto's data model allows no other numeric type — clients must never write a fractional value here.",58
"type": "integer"59
},60
"rank": {61
"description": "The malleable sort strategy's pinned position, on the same numeric axis as color rank scaled by RANK_SCALE (1024) — see the app's config.ts. Set when the user drags this task while that strategy is active; cleared when its color changes, rejoining the color grouping. Supersedes the legacy `movedRank` field, which used an unscaled axis with no integer headroom to halve into.",5862
"type": "integer"5963
},6064
"recByMonth": {6165
"description": "Yearly only: the month (1=January … 12=December). Omitted means the anchor's month.",6266
"maximum": 12,6367
"minimum": 1,6468
"type": "integer"6569
},6670
"recByMonthDay": {6771
"description": "Monthly & yearly \"day\" mode: the date-of-month. Omitted means the anchor's date. Months without this day are skipped.",6872
"maximum": 31,6973
"minimum": 1,7074
"type": "integer"7175
},7276
"recByWeekday": {7377
"description": "Weekly only: weekdays the series lands on (0=Sunday … 6=Saturday). Omitted means just the anchor day's weekday.",7478
"items": {7579
"maximum": 6,7680
"minimum": 0,7781
"type": "integer"7882
},7983
"type": "array"8084
},8185
"recCount": {8286
"description": "Optional: end the series after this many occurrences, counted from the anchor (inclusive).",8387
"minimum": 1,8488
"type": "integer"8589
},8690
"recFrequency": {8791
"description": "How often the task recurs.",8892
"enum": [8993
"daily",9094
"weekly",9195
"monthly",9296
"yearly"9397
],9498
"type": "string"9599
},96100
"recInterval": {97101
"description": "Recur every N frequency units (e.g. every 2 weeks).",98102
"minimum": 1,99103
"type": "integer"100104
},101105
"recMonthly": {102106
"description": "Monthly & yearly: land on the calendar date-of-month (\"day\") or the anchor's nth weekday (\"weekday\", e.g. the 2nd Friday). Omitted means \"day\".",103107
"enum": [104108
"day",105109
"weekday"106110
],107111
"type": "string"108112
},109113
"recUntil": {110114
"description": "Optional last occurrence day (YYYY-MM-DD), inclusive. Set directly or kept in sync as the concrete stop date when recCount is used.",111115
"type": "string"112116
},113117
"stamps": {114118
"ref": "#stamps",115119
"type": "ref"116120
},117121
"subtasks": {118122
"items": {119123
"ref": "#subtask",120124
"type": "ref"121125
},122126
"type": "array"123127
},124128
"title": {125129
"description": "The task title. May contain inline Markdown (links and emphasis); clients that don't render Markdown can show it as plain text.",126130
"maxLength": 500,127131
"type": "string"128132
},129133
"updatedAt": {130134
"description": "Last local edit; used as the whole-record last-write-wins clock during sync. The physical component of a hybrid logical clock, so it is monotonic per device.",131135
"format": "datetime",132136
"type": "string"133137
}134138
},135139
"required": [136140
"title",137141
"completed",138142
"order",139143
"createdAt",140144
"updatedAt"141145
],142146
"type": "object"143147
},144148
"type": "record"145149
},146150
"stamps": {147151
"description": "Per-field-group hybrid-logical-clock stamps (an approach borrowed from the CRDT ideas behind automerge.org), enabling field-level last-write-wins merges: two devices editing different groups of the same task both keep their edits. Each value is '<ISO datetime>.<counter hex4>.<device id>', totally ordered by plain string comparison. Absent on a group (or entirely, on records from before stamps existed) means updatedAt stands in for it. Clients that don't merge field-wise can ignore this and compare updatedAt whole-record.",148152
"properties": {149153
"color": {150154
"description": "Covers color.",151155
"type": "string"152156
},153157
"done": {154158
"description": "Covers completed and completedAt.",155159
"type": "string"156160
},157161
"notes": {158162
"description": "Covers description.",159163
"type": "string"160164
},161165
"place": {162166
"description": "Covers day, order, movedRank, and movedAt, which move together.",163167
"type": "string"164168
},165169
"recurrence": {166170
"description": "Covers isRecurring and every rec* field.",167171
"type": "string"168172
},169173
"subtasks": {170174
"description": "Covers subtasks.",171175
"type": "string"172176
},173177
"text": {174178
"description": "Covers title.",175179
"type": "string"176180
}177181
},178182
"type": "object"179183
},180184
"subtask": {181185
"properties": {182186
"completedAt": {183187
"description": "When `done` last flipped to true. Used to order completed subtasks by completion time.",184188
"format": "datetime",185189
"type": "string"186190
},187191
"done": {188192
"default": false,189193
"type": "boolean"190194
},191195
"id": {192196
"type": "string"193197
},194198
"text": {195199
"maxLength": 500,196200
"type": "string"197201
}198202
},199203
"required": [200204
"id",201205
"text",202206
"done"203207
],204208
"type": "object"205209
}206210
},207211
"id": "town.chalky.task",208212
"lexicon": 1209213
}