full diff

town.chalky.task

chalky.town +7 −3
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": 1
209213}

Compare other versions