Clestr-01 (Curated Layer of Educational Stuff Transmitted by Relays)
Clestr-01 (Curated Layer of Educational Stuff Transmitted by Relays)
What this tries to solve
Free educational content exists everywhere on the internet, but is not well organized. Dedicated websites like Khan Academy, edX, Coursera, and MIT OpenCourseWare host and organize their own centralized free content, but each remains disparate from one-another. Platforms like YouTube, Medium, and Substack contain a mix of educational content and entertainment (which can be distracting). Search engines help users find individual pieces of content, and people and corporations can organize and curate that content via existing platforms, but those lack harmony. Clestr is a protocol built on Nostr to address these pain points and create an open method for organizing, curating, and collaborating on new and existing educational content on the internet.
Vision
- Anyone can curate their own learning pathways and share with others
- The "best" individual content from different sources can be combined to
provide a complete curriculum.
- Content on the same topic by different creators can be organized as
alternatives that may be better fit for people with different needs or learning styles
- Users maintain control over their experience (no unwanted vying for attention)
- WoT (Web of Trust) allows users to build reliable decentralized networks of
skills, endorsements, and content
- The protocol can act as a layer on top of a user's browser experience, giving
them access to curation tools wherever they are
Protocol Notice
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14 RFC2119 RFC8174][] when, and only when, they appear in all capitals, as shown here.
Nostr Relay
MUST serve a [NIP-01][] compliant nostr relay at /.
MAY reject or delete events for generic SPAM prevention reasons or curation eg. WoT, whitelist, user bans and banned topics up to the relay's discretion.
It is RECOMMENDED that the relay implement [NIP-50][] (Search)
Client Behavior
The client MAY operate as a web browser plugin, a standalone app, or a website with embedded & linked content.
SHOULD implement the following for complete feature set:
- [NIP-02][] (Follow List)
- [NIP-19][] (bech32-encoded entities)
- [NIP-22][] (Commenting)
- [NIP-23][] (Long Form Content)
- [NIP-25][] (Reactions)
- [NIP-50][] (Search Capability)
- [NIP-51][] (Lists)
- [NIP-54][] (Wiki)
- [NIP-58][] (Badges)
- [NIP-71][] (Video Events)
- [NIP-73][] (External Content IDs)
- [NIP-84][] (Highlights)
- [NKBIP-01][] (Curated Publications)
MAY implement:
- [NIP-37][] (Drafts)
- [NIP-GRAPEVINE-API][] (Grapevine WoT)
Many of these protocols are broadly supported by other clients which makes clestr adaptable to support and render content produced by other clients without modification.
Client UX Example Implementation Ideas
Client A - Browser Plugin
Users interact with their browser as usual. When visiting videos and webpages across the internet the plugin MAY search relays to see if the current page has been referenced in any courses/curricula and render or inform the user of this. As users interact with the page they may decide to mark the content as completed, or view it in the context of the surrounding course/ curricula. They could open it up to see other user's comments on the external link or the curated learning paths.
Client B - Webapp or Desktop app
Rather than overlaying the live web like the browser plugin, this client pulls referenced content into a Clestr-controlled surface. When a learning path references an external URL (a video, article, or interactive page), the client renders it in a sandboxed iframe with Clestr controls layered around it — mark-complete, highlight, and comment affordances drawn from the surrounding course or curriculum. Because many sites refuse embedding via X-Frame-Options or a CSP frame-ancestors directive, the client MUST detect a blocked frame and fall back to opening the resource in a new tab while still displaying the Clestr context (position in the path, prerequisites, peer comments) alongside the link. Untrusted embeds SHOULD carry a restrictive sandbox attribute. Where Client A annotates the open web in place, Client B brings the web into a curated reading environment — the same events and trust graph drive both.
Curation Layer
Clients SHOULD author new 30041/30818 content in Djot (See [NIP-54][]'s choice for reasoning).
Clients SHOULD also parse AsciiDoc because [NKBIP-01][] 30041 in the wild uses it.
Clients MUST resolve both wikilink conventions — [NIP-54][] Djot reference-style [term][] and [NKBIP-01][] double-bracket [[term]] — to kind 30040/30041/30818 by normalized d tag.
Users SHOULD curate or create organized educational content in the form of curricula/courses and in a combination of kind 30040/30041.
Clients MUST implement creation and rendering of the course and curriculum publication indices & content.
URL Normalization for External Content
When matching the user's current location against externally addressed content ([NIP-73][]) and when authoring r/i references, clients SHOULD apply best-effort normalization so the same resource resolves to the same address regardless of how the user arrived at it. The same normalization routine SHOULD be used for both matching and authoring, so that a reader and an author independently arrive at the same identifier.
Clients SHOULD:
- Lowercase the scheme and host, prefer
https, drop default ports
(:80/:443), and strip a trailing dot on the host.
- Strip known tracking and session parameters (e.g.
utm_*,fbclid,
gclid, mc_eid, igshid, ref, ref_src).
- Remove the URL fragment unless it is known to be content-identifying.
- Apply platform-specific canonicalization for well-known hosts, collapsing
equivalent forms to a single identifier — e.g. resolving youtube.com/watch?v=ID, youtu.be/ID, youtube.com/shorts/ID, and youtube.com/embed/ID to the same video, and where [NIP-73][] defines a dedicated identifier kind for that platform, addressing by that ID (i) rather than the raw URL (r).
Clients SHOULD preserve query parameters that are content-identifying (e.g. v= on YouTube) and SHOULD NOT reorder or alter parameters whose semantics they do not recognize. Clients MAY retain the original, pre-normalized URL alongside the normalized identifier for display and linking.
Because normalization is necessarily incomplete, clients SHOULD treat a missing match as "no curation found" rather than authoritative, and MAY fall back to host-level or fuzzy lookups to surface related content.
Kind 1985 Labels [NIP-32][]
Use is up to the discretion of the client and the user, but they MAY for example use them to categorize content according to an ontology or classification like the Dewey Decimal Classification, [Universal Decimal Classification][UDC], [Wikipedia-style category tree taxonomy][wiki-categorization], [Thema Subject Categories][thema]
Labels MAY also be used to classify content by educational goals like [Blooms Taxonomy][].
e.g.
["L", "blooms_taxonomy"],
["l", "understand", "blooms_taxonomy"],Kind 30004, 30005, 30006 Curation Sets [NIP-51][]
SHOULD avoid these kinds in preference of kinds 30040 and 30041 for curation.
Clients MAY still choose to provide these, but they SHOULD note the intended uses and differences.
Kind 30009 Badge Definition [NIP-58][]
SHOULD be used to define skill competency badges that users can issue to eachother
SHOULD be used to define milestone or course completion badges that users can self-assign and assign to eachother. Milestones may include things like capstone projects, diplomas, degrees, and certifications to name a few.
Kind 30023 Long-form [NIP-23][] (Blogs / Articles)
Clients MAY implement authoring events of this kind.
Users MAY create educational content from events of this kind.
Kind 30040 Publication Index [NKBIP-01][]
- MUST allow the following list of referenced event kinds:
- 30023 (long-form content)
- 30040 (nested hierarchical Publication Index)
- 30041 (publication content)
- 30818 (Wiki content)
- SHOULD use the
typetags:
coursefor collection of content that represents a full course (e.g.
Plumbing 101 - Intro to plumbing)
curriculumfor a nested curriculum of courses and content (e.g. Computer
Science - Video Game Development Track)
- Within kind 30040,
qdenotes a prerequisite reference.
- MAY contain one or more
qtags to specify required/prerequisite content by
their normalized d tag according to [NIP-54][] and optionally the level of proficiency required (short note like "basic proficiency" or blooms taxonomy level)
- SHOULD allow
defermarkers like wiki-events in [NIP-54][]
Example event:
{
"id": "<event_id>",
"pubkey": "<curator_pubkey>",
"created_at": 1730000000,
"kind": 30040,
"tags": [
["d", "mig-welding-101-by-acme-trades"],
["title", "MIG Welding 101"],
["type", "course"],
["summary", "An introductory course on MIG welding, from machine setup to your first structural welds."],
["auto-update", "ask"],
["q", "shop-safety"],
["q", "using-a-wrench", "basic proficiency"],
["a", "30041:<author_pubkey>:mig-welding-101-intro", "wss://relay.example.com", "<event_id_1>"],
["a", "30041:<author_pubkey>:mig-welding-101-machine-setup", "wss://relay.example.com", "<event_id_2>"],
["a", "30040:<author_pubkey>:mig-welding-101-first-welds", "wss://relay.example.com", "<event_id_3>"],
["p", "<original_author_pubkey>"],
["E", "<original_event_id>", "wss://relay.example.com", "<original_author_pubkey>"],
["source", "https://acmetrades.example.com/courses/mig-101"],
["version", "2nd edition"]
],
"content": "",
"sig": "<event_signature>"
}A client builds the prerequisite graph by walking q edges: for each tag, resolve the d tag to a publication (via WoT among the alternatives), then recurse into that publication's own q tags. Each node is keyed by normalized d tag, so a skill reached by several paths (e.g. "shop-safety" required by many courses) is deduped to one node. The client MUST guard against cycles — a malformed q loop must break, not hang — and MAY topologically sort the result to suggest a learning order. Crucially, prereqs render in a different place from a content: the a list is the reader/chapter view, while q edges render as a prerequisite panel or as upstream nodes in a graph view. An index with only references and empty content (a bare map) SHOULD default to the graph view; a content-bearing index defaults to the reader view.
As defined in [NKBIP-01][] the p/E/source/version tags credit and link the original work this course was forked from; omit them for an original.
Kind 30041 Publication Content [NKBIP-01][]
- SHOULD use [NIP-73][] tags for externally addressed content in which case the
content field is optional, which if specified, acts as summary or description of the addressed content.
NOTE: Wrapping externally addressed content via [NIP-73][] in a kind 30041, allows it to be queryable by its [NIP-54][] formatted d tag and be compared to other similar content
Kind 30818 Wiki Content [NIP-54][] (Descriptions, Encyclopedia, WikiHow)
Clients MUST implement creation and rendering of wiki content. Including rendering wikilinks to kind 30040 and 30041 content.
Users MAY create educational content found in events of this kind.
Clestr Wikilinks
Clients MUST be able to render wikilinks (as described in [NIP-54][]) that can reference the following kind 30040, 30041, and 30818 by d-tag.
Client SHOULD show alternatives when different users have created entries for the same d-tag. See [NIP-54][] "How to decide what article to display"
Web of Trust
If available, [Grapevine WoT APIs][NIP-GRAPEVINE-API] MAY be used to filter content by trustworthiness.
It is RECOMMENDED to implement trust in the following order or precedence:
- [NIP-54][]
defertag (for kind 30818/30040) - [Grapevine WoT score][NIP-GRAPEVINE-API] if available
- [NIP-58][] kind 8 badge awards from trusted issuers
- [NIP-51][] kind 10101 /10102 Good wiki authors and relays
- [NIP-51][] kind 30000 follow sets
- [NIP-02][] kind 3 follow lists
- [NIP-25][] kind 7
+reactions - [NIP-25][] + [NIP-73][] kind 17 external content reactions
Raw [NIP-25][] reaction counts can be gamed, and thus SHOULD only count when reachable through the user's trust graph, not globally.
Learner Experience
Kind 1985 Labels [NIP-32][]
Learners SHOULD be able to mark learning path items as complete by assigning labels namespaced under clestr, e.g. in-progress, complete
Client SHOULD allow users the option to store progress as a [NIP-59][] Gift Wrap event for keeping kind 1985 private
Kind 9802 Highlights [NIP-84][]
(of nostr content and external URLs, with optional context and comments)
Learners SHOULD be able to highlight content on the internet and content hosted by nostr for later referencing.
Kind 10003 Bookmarks & 30003 Bookmark Sets [NIP-51][]
Learners SHOULD be able to mark their enrolled courses and learning paths by bookmarking them (either their global bookmark, or a defined set)
Kind 10008 Profile Badge [NIP-58][]
Learners SHOULD be able to don their achievements
Kind 10015 Interests [NIP-51][]
Learners SHOULD be able to share their interests
Kind 10101 Good Wiki Authors & Kind 10102 Good Wiki Relays [NIP-51][]
Learners SHOULD be able to mark authors and relays as good for wiki content. The same lists MAY be used to mark curated content (not just Wikis, but also the Publication Indexes used for curricula and courses)
[NIP-01]: https://nostrhub.io/nip/01 [NIP-02]: https://nostrhub.io/nip/02 [NIP-19]: https://nostrhub.io/nip/19 [NIP-22]: https://nostrhub.io/nip/22 [NIP-23]: https://nostrhub.io/nip/23 [NIP-25]: https://nostrhub.io/nip/25 [NIP-32]: https://nostrhub.io/nip/32 [NIP-37]: https://nostrhub.io/nip/37 [NIP-50]: https://nostrhub.io/nip/50 [NIP-51]: https://nostrhub.io/nip/51 [NIP-54]: https://nostrhub.io/nip/54 [NIP-58]: https://nostrhub.io/nip/58 [NIP-59]: https://nostrhub.io/nip/59 [NIP-71]: https://nostrhub.io/nip/71 [NIP-73]: https://nostrhub.io/nip/73 [NIP-84]: https://nostrhub.io/nip/84
[NKBIP-01]: https://nostrhub.io/naddr1qvzqqqrcvypzplfq3m5v3u5r0q9f255fdeyz8nyac6lagssx8zy4wugxjs8ajf7pqqyxu6mzd9cz6vp3tn64lg [NIP-GRAPEVINE-API]: https://nostrhub.io/naddr1qvzqqqrcvypzqlxr9zsgmke2lhuln0nhhml5eq6gnluhjuscyltz3f2z7v4zglqwqqgku6ts94nhyctsv4mxjmn994shq6g774x0d
[wiki-categorization]: https://en.wikipedia.org/wiki/Wikipedia:Categorization [UDC]: https://en.wikipedia.org/wiki/UniversalDecimalClassification [thema]: https://ns.editeur.org/thema/en [Blooms Taxonomy]: https://en.wikipedia.org/wiki/Bloom%27s_taxonomy
[BCP 14 RFC2119 RFC8174]: https://www.rfc-editor.org/info/bcp14/