Need Protocol for Task/Todo events and lists
I’m looking for help designing a Nostr-native structure for tasks/todos. As far as I can tell, no NIP defines this yet and I’d appreciate feedback from anyone who has thought about similar multi-writer/shared-object patterns.
I want my project to be protocol compliant but I can't find anything that works with my use case. I’m currently exploring a reminder/task format modeled loosely on NIP-52 (calendar events). Tasks would be individual events. Lists would be their own kind, referencing task event IDs. Boards would mirror lists, but reference lists instead of tasks. All of these objects need to be replaceable by anyone with access to the board.
Right now in Taskify, board access is handled by deterministically deriving a signing key from the board ID. Extending this down to the task level via child keys feels workable but potentially brittle and overly complex. I’m hoping there’s a cleaner pattern or an existing precedent for multi-writer replaceable events.
If anyone knows of prior solutions or has thoughts on a better structure, I’d love input.
Constraints • Events must be replaceable/deletable by multiple authorized users • Titles/content must be encrypted and visible to anyone with the board ID or secret • Ideally shareable at the task level (task access ≠ full board access, but full board access ⇒ task access) • Bonus: a clean way to support read-only access
This has been tackled a few times: https://github.com/nostr-protocol/nips/pulls?q=is%3Apr+is%3Aopen+kanban+
I'm not sure how active any of these proposals are, but that would be a good place to start. Based on your description of your use case, I'm not sure any current proposals are really going to do the trick, since use cases that require access control or collaborative editing are much more difficult on nostr due to the lack of a single source of truth and the inability to replace events created by someone else. Encryption can work, but it makes things much less scalable, and much more complex, for not a lot of benefit.
Here's a quick sketch for how I would approach this:
- Implement authorization by specifying canonical relays for a given board (see nip 29, relays as groups). These relays can then implement arbitrary policies for any user/board/list/task combination. This supports all auth-related constraints you mentioned. You might even be able to overload a nip29 room as a "board", which would allow for nip 29 clients to trivially add support for your NIP without having to re-implement authorization.
- Use opaque string ids for all objects in the system. For example, to create a task 123 on list 456 on board 789, you would do something like
{kind: <non-replaceable-kind>, content: "my task", tags: [["d", "1234"], ["l", "456"], ["h", "789"]]}. This allows anyone to say whatever they want about those IDs, leaving it up to the client to merge updates into a current board state. Of course, the downside of this is that you have to keep history around, but the upside is a full audit log. You could also use a custom relay that prunes events that are no longer relevant (I would recommend using PUT rather than PATCH semantics so that if a task is updated the old event can be dropped).
Just some quick ideas, don't take anything here too religiously (especially my use of the l tag above). Hope that's helpful though.