CoPonder roadmap
Direction only. Nothing here is built until the owner adds that phase's full spec to coponder.md. Use it to keep today's choices from blocking later features.
What CoPonder becomes
CoPonder is your digital ocean (owner, 2026-10-14). Underneath, two ideas: the drop, one piece of writing or art whose setting says who sees it (only you, your pond, or everyone), and the pond, drops together, which reads in order like a playlist: your profile, a book, a webcomic, a gallery, a community. A thought starts in your notebook, grows in your pond and goes out to the ocean. See wiki/Vision.md and wiki/Design/Drops and ponds.md.
Around them, three layers in one binary:
- Twitter layer (built): profiles, follows, timeline, reposts, quotes, likes.
- Reddit layer: communities, voting, threaded discussion, a read-only knowledge base built from each community's own answers, and moderators who judge rather than police.
- Discord layer: live chat channels in communities, plus end-to-end encrypted DMs and private groups.
Plus an optional ambient fishing game whose cosmetics fund the worker co-op. No ads, no data sales, no venture money.
Rules for growth
- One Go binary, SQLite, server-rendered HTML. No new database or service: SQLite FTS5 replaces Typesense, goroutines replace Phoenix Channels, and plain tables replace a graph database.
- Each phase is specced in coponder.md before it's built, with a line budget (aim under 800 lines of Go per phase).
- Every phase follows coponder.md's Privacy section, manifest included.
- New private per-user state goes in the vault. Public counts of private actions use anonymous markers, the same pattern as private likes.
- Migrations stay additive. A phase that can't be rolled back says so.
- Work that calls AI models runs as separate subcommands (
coponder classify,coponder wiki) on systemd timers, never inside the web server, and reads only public data.
Constraint changes the roadmap will need
Each one is an owner decision when its phase is specced.
| Constraint today | Change | Phase |
|---|---|---|
| The server makes no outbound requests | Worker subcommands may call InferenceURL (default: a model server on localhost); the web server still makes none |
20 |
CSP frame-ancestors 'none' |
'self' on chat frames only |
24 |
| No JSON API | A ciphertext mailbox endpoint for the local encrypted client | 25 |
| Standard library plus go-sqlite3 | Plus a vetted MLS library | 25 |
What's next
- Moderation you can see. Appeals are built: a removed drop waits, hidden, for 90 days, you're told who removed it and why, and someone other than whoever removed it decides your appeal. Next: a public log of each pond's moderation, and a way for members to replace a moderator.
- Tags you can combine. Built: search
#book #fantasy #adventureand get what has all three, with or without commas. Books, comics and galleries carry their kind as a tag on their own, so#bookfinds every book. - Video uploads. Built: drop a video up to 12 minutes. With JavaScript on, what you pick, drag in or paste shows in the box at once, and a bar fills as it uploads, big videos in pieces.
- An Obsidian plugin, so your notes can move between CoPonder and Obsidian.
Along the way: clearer pages and design polish.
Later: live chat and private messages. Chat has to fit the way ponds work, ponds inside ponds included, and that needs more thought first.
Phases
18. Communities (the Reddit core) โ built
- Communities.
communities: slug (same rules as handles), name, description, creator, created (day), status. Only accounts older thanCommunityMinAccountDayscan create one, at mostCommunitiesPerUsereach. A community with no drops 30 days after creation is reclaimed and its slug freed. - Drops.
posts.community_idis nullable: a drop lives on a profile or in one community. Replies inherit the root's community. - Joining is private. Joined communities live in the vault, and member counts come from anonymous markers (HMAC(DK, "join:" + community id)).
- Votes were ๐/๐ at first, and since 30 October 2026 they are their own โฌ๏ธ and โฌ๏ธ arrows on every drop, as on e621. Community feeds sort New (by id) or Top (โฌ๏ธ minus โฌ๏ธ over a day, week, month, year, or all time). No engagement-ranked "hot" feed.
- Home tabs: Everything (follows plus joined communities), Joined, Following.
- Moderators. The creator is the first moderator, mods appoint mods, and the mod list is public. A community with no mods is "unmoderated": a banner asks for volunteers, and its reports wait for admins.
- Community page tabs: Feed now; Wiki (21) and Ghost (23) later.
18b. Pond links, and one drop in several ponds (Obsidian-style) โ built
- Links, resolved when shown.
[[story-writing]]links a pond,[[story-writing/43]]a drop. Drops store the text as typed; links are worked out each time a page renders, so[[someday]]shows faded (like Obsidian's unresolved links) until a pond called someday exists, then links by itself. No limit on links. - Home pond. A drop written in a pond's own box belongs to that pond. Its edit form shows the pond in a properties block; deleting it untethers the drop and its thread (owner's later choice).
- Other ponds follow the text.
[[!story-writing]]in a top-level drop also puts it in that pond, if the author is a member when the drop is saved; otherwise it's just a link. Edits count as saving: removing the tag takes the drop out of that pond, adding it (as a member) puts it in. Never backfilled: joining later doesn't add old drops. No limit on how many ponds (owner: trust people, mods clean up; add a cap only if spam appears). Replies stay in their thread's pond (!is just a link there). - Putting a drop in a pond this way shows the author is a member of that pond, as dropping inside it already does.
- A pond's moderators can take a drop that came from another pond out of theirs; that sticks, and the tag stays a plain link for that pond even if the author edits again.
- Shown as "also in pond/x"; a drop's address uses its home pond (or its author's drops folder if it has none).
- Properties (an Obsidian-style
---block at the top) are built for drops: hidden, putting a drop in other ponds, and holding a pond drop's home pond so it can be untethered. Personal pond pages will use them too (public: trueand the like).
18c. Private ponds โ built (2026-10-13)
- Ponds are Public, Members only, or Members only, locked. A drop's
members-only:line (written by a button) says who reads it; members-only drops are hidden from outsiders everywhere and labelled "the people who run the site can read this pond". - Joining a members-only pond is by invite link from its moderators or admins; one link can also sign a new person up. One drop, one audience: a drop can't be public and members-only at once. Going public needs the author's consent (and a moderator's in a locked pond).
- Bans and unbans: only after a report from someone else, by a majority vote of the pond's moderators.
18d. Notebooks: drops and ponds โ building (owner, 2026-10-13 and 14)
The agreed design is wiki/Design/Drops and ponds.md. It's built one step at a time, each specced in coponder.md first.
- Drops everywhere (step 1, built): every label and help text says drop; a profile's tabs are Drops, Replies, Wall and Likes, and the button says Drop.
- Every pond, the same two settings: who can drop in (anyone, members, or only its moderators) and who can see (anyone, members, members locked, hidden, or only me).
- Books, comics and galleries: a pond only its moderators drop into opens on its Contents, and every drop in a pond gets โ Previous ยท Contents ยท Next โ. Move drops up and down. One drop can sit in many ponds, by reference, never copied, and Next follows the pond you came from. Anyone's public drop can go in your pond, still credited to them.
- Your ponds: a Ponds tab on your profile and + New pond, at
/@ana/my-book. Ponds hold ponds (a book's Part 1 and Part 2, at/@ana/my-book/part-1), and a whole pond can be reposted. - Titles: an optional
title:in a drop's properties, following Obsidian's file-naming rules, gives it a second address in its pond (/pens/Whats-the-best-pen) and links like[[pens/Whats the best pen]]. A title already taken in that pond gets an error that links to the original and suggests adding the year. - Hidden ponds: members only, locked, and shown nowhere to outsiders; you find one only through its invite link.
- Your notebook: your profile, with everything you made. ๐ Private (
public: false) keeps a drop, its pictures or a whole pond for you alone, stored encrypted with your key; ๐ Make public sends it out. - Later: download your notebook as Obsidian folders; an Obsidian plugin that publishes notes marked public.
- Personal pages were first sketched here as
/pond/@handle, a free "digital garden" inside a community; your ponds under your name replace that sketch.
19. Moderation: judges, not police
-
Built so far: the mod log (admins only, the owner's choice; 365 days), strikes, 18+ marking by pond moderators, and pond bans and unbans by majority moderator vote after a report (18c).
-
Built (owner, 2026-10-13; built 2026-10-16): a report queue for each pond (user reports only), where its moderators verify (remove, or mark 18+) or dismiss; law and ToS reports, and reports on a moderator's own drops, stay with the admins; the anomaly rule with user re-reports only (anonymous report markers); and pond rules shown above its box. See coponder.md, Pond queues and Pond rules.
-
Built (owner, 2026-10-23): appeals. A removed drop's words, pictures and video wait, hidden, for 90 days, its author is told who removed it and why, and another moderator of the pond, or the admins, restores it where it was or keeps it removed. Illegal content is deleted at once, with no appeal. See coponder.md, Holds and appeals.
-
Built (owner, 2026-10-29): a group's pond nobody has dropped anything in for 90 days can be deleted by a majority of its moderators, the same vote as a ban. Every drop in it stays its author's, and its address is never given to another pond.
-
Still to come: members' petitions to remove a mod, AI flags (phase 20), and a public per-pond mod log.
-
One queue per community, with three sources kept apart: user reports, appeals, and AI flags (from phase 20).
-
Mods only verify or dismiss. Verifying removes the drop in that community: it's gone for everyone, and its author and the admins see it as [REMOVED]. Mods can't remove or ban on their own initiative.
-
mod_logrecords every mod and admin action: who acted, the action, target, source, and day. It's public per community and never holds reporter identity. -
Anomaly rule. If a mod dismisses three items within
ModAnomalyDaysthat are later re-flagged (by other users, or by the AI with higher confidence), that mod is surfaced to admins. -
Members can petition to remove a mod. Admins decide from the mod log, not from vote counts.
-
Admins oversee mods and handle site-wide law and ToS issues. They don't moderate community rules.
-
Answered by the owner (built early): admins give strikes; 3 within a year remove the account, keep its drops as [REMOVED] for the admins alone, and retire the handle for good. Pond moderators can mark drops 18+. See coponder.md, the Strikes and 18+ sections.
20. Classification
- The worker.
coponder classifyruns on a timer every minute. It sends unclassified public drop text, and nothing else, toInferenceURL, then stores:posts.kind: question, discussion, or informational;posts.rolefor replies: to questions, answer, expansion, follow-up, or noise; to informational drops, support, refute, context, or noise.
- The site works without it. Unclassified drops are normal drops. An outage just leaves a backlog, drained at
ClassifyPerMinute. - Reclassification. Members can vote to reclassify. The threshold starts at 3 and grows with the log of community size, weighted by contributing status once phase 22 exists. Reclassifying a drop re-queues its replies.
- Display. Tags are small and plain; correcting one is a link.
- Cost guard. Drops from accounts over the rate limit for dropping wait in the batch queue.
21. Knowledge base
- Source threshold.
coponder wikigenerates entries from question and informational drops with at least 3 classified responses, including at least one answer, or one support or refute. - Quotes are references, not copies. An entry is AI-written connecting text plus quote references stored as (drop id, start, end) offsets into the source drop. Quotes render from the live drop at view time, so deleting a drop removes its quotes everywhere with no extra work. The generator rejects any output whose quotes don't match the source exactly.
- Counts and disagreement. Counts in entries ("22 users said...") link to searches. Disagreement is shown, not resolved.
- Years and links. One entry per topic per year; older years stay as linked history and never outrank newer ones. Related entries are linked by FTS5 similarity of their text, with no embeddings and no vector store.
- Drops from other ponds (from 18b). Suggested: a pond's wiki reads both the drops whose home it is and those put in it from other ponds (the author, a member, chose to put them there; moderators can already take ones that don't fit out). The difference stays in the data (
posts.community_idvscrossposts) in case they should count differently. Open: replies live in the thread's home pond, so the answers to a question put in from another pond may come from people outside the pond; decide when this phase is specced. - Read-only. Bad output (incoherent text, a broken quote, misleading connecting text) can be flagged for regeneration through the mod queue.
- Where it shows. A Wiki tab on communities, and profiles list the entries that quote the user.
- Check the wiki first. Submitting a question goes to a confirm page listing matching entries, with a "Drop anyway" button.
- Open question for the owner: whether quoting needs a content license at signup (the old CC BY-SA idea). Under the privacy rules, deletion removes quotes either way.
22. Contributing members
- Points, per community: 3 for each reply quoted in a wiki entry, 1 for each question or informational drop. Status comes at 9 points with at least one quoted reply. All numbers are tunable in internal/config/config.go.
- Kept by activity. A
last_active_monthper (user, community), stored as a month only. Status lapses afterContributorIdleMonthsand returns with new activity. - Computed nightly from drops and wiki references, with no event log.
- What it gives: weight in reclassification, and adoption power in the Ghost feed.
23. Ghost feed
- The classifier may tag a question or informational drop made on a profile or in another community as relevant to a community (
ghost_tags). Discussion drops are never tagged, and the author isn't notified. - A community's Ghost tab appears once it has
GhostMinContributorscontributing members. Adoption needs 5% of them, with a floor of 2. Adopted drops join the community feed.
24. Live chat (the Discord core)
- Design drafted (2026-10-16): wiki/Design/Live chat.md; owner's questions open.
- Text channels in communities. Messages render as HTML into an iframe whose response never ends: the server writes each new message and flushes. The composer is a form in a second frame. Text browsers get a page that reloads.
- Connections. One goroutine per open stream and one broadcaster per channel, with caps on open streams per account and in total. Long-lived stream routes get their own deadlines.
- Members-only channels are labeled. Channels are public or members-only, and a members-only channel's header says "The people who run the site can read this channel." Messages are deleted after
ChannelRetentionDays(default 30). - Presence (who's online) lives in memory only and is never stored.
- Out of scope: voice and video, which need WebRTC and JavaScript.
25. End-to-end encrypted messages
- Protocol. DMs and private groups use MLS (RFC 9420) through a vetted Go library, chosen when this phase is specced. Never a homemade protocol.
- The client is your own copy of the binary. It runs on the user's machine as
coponder client: it holds the keys, serves a localhost-only HTML page with no JavaScript, and talks to the server through a minimal ciphertext mailbox. Because users run their own copy, the server can't hand them modified code, which a served web page can't guarantee. - The server holds ciphertext only. It stores ciphertext and delivery queues, addressed by random mailbox ids rather than account ids where MLS allows, and deletes them after delivery or after
MailboxDays. - Verifiable releases. Reproducible builds with published hashes.
- Mobile clients come later.
26. Fishing game and cosmetics
- Optional script. Off by default (a Settings switch), desktop only, one script served from the site, like the others.
- The game. Characters idle and fish at the bottom of community pages alongside others browsing the same community. Positions and presence live in memory only.
- Cosmetics are a fixed catalog in the code (hats, rods, outfits), with no user-made content. Owned items are public, since they show on profiles.
- Paying never links to an account. People buy redeem codes outside the site, for example through a Stripe payment link that involves no account, then redeem them in Settings. The code row is deleted on redemption. Memberships work the same way with time-limited codes. The server never calls Stripe.
- Kickstarter founding rewards are redeem codes too.
27. Public data and co-op tools
- Bulk download and Atom feeds of each community's public wiki entries. Business access gets this same public data, rate limited: no private data and no special deals.
- Co-op governance (members electing admins) once the co-op exists.
Video uploads (built 2026-10-21)
- Built: any account can drop a video up to 12 minutes, played with controls, not looped. Every video is remade as a small MP4 that plays everywhere, without its location, before the drop goes up. Files live beside the database, not in it.
- Built too: a small optional script for uploads. Pictures and videos show in the box as soon as you pick, drag or paste them, each with an ร to take it out, a bar fills as they upload, and big videos go up in pieces, so a video over 100 MB gets through. Without JavaScript, a video over 100 MB still can't.
The notes from before it was built:
- Built first (2026-10-14): GIFs. Uploaded and copied GIFs stay animated, GIF-site clips (Discord's GIF picker, Klipy, Tenor, Giphy) are copied as-is and play like a GIF, and stored GIFs get a small MP4 clip made by ffmpeg, the one approved outside program.
- What the owner wants (2026-10-14): video drops up to 12 minutes, played with controls, not looped; start there and see how it goes.
- The blocker: the free Cloudflare tunnel refuses uploads over 100 MB, and a 12-minute phone video is usually bigger. Options to weigh then: shrink on the phone, upload in parts, or uploads that skip the tunnel (the move to a rented server with Caddy). Video through the free tunnel may also be against its terms.
- The earlier plan: played with the browser's own
<video controls>, no JavaScript; every upload converted to H.264/AAC MP4 with metadata (GPS included) stripped; 18+ hiding applies; files on disk, not SQLite blobs, so backups don't bloat. - Risk: video is where the worst illegal content appears and nothing scans automatically; moderators (phase 19) should be in place.
Small items, any time (vault-based)
- Cleanup after 2026-10-22: once maintenance has run
dropLegacy(LegacyPrivateDays after the private store started), remove the one-time legacy move (moveLegacy,dropLegacy,legacyUsers,LegacyPrivateDays, the login hook), about 100 lines. Thelikes/dislikes/mutestables are already retired in the manifest. - Bookmarks (built 2026-10-16): a vault list. ๐ Bookmark in a drop's โฏ menu keeps it in ๐ bookmarks, a folder in your notebook only you see, locked with your key; nobody is told. See coponder.md, Bookmarks.
- Recovery code (built): shown once at signup. DK is also wrapped with a key derived from it, so a forgotten password can be reset without losing private data and without email.
- Private notes on profiles (built 2026-10-16): on anyone's page, a short note only you see ("met at the zine fair, does lettering"), kept in your vault, in your download as
notes on people.md. See coponder.md, Private notes on people. - Admin page reorganization (built 2026-10-16): the admin page has grown and needed sorting. Now five tabs, To do first (lookouts, ponds' queues, the admins' reports), then Accounts, Ponds (with the โญ shelf), Log and Wiki. See coponder.md, Admin.
Owner actions outside the code
- A rented server with Caddy, off Cloudflare, plus a Tor onion address as a second way in.
- Co-op-owned hardware later.
Not planned
Federation, ads, analytics, selling data, email, phone numbers, voice and video chat, a general JSON API.