2026-05-31 13:12:30 +00:00
# AGENTS.md — eutopic
eutopic is a photo-first social app for small, trusted, invite-only communities.
not a global network. not optimized for engagement or attention.
target: 5– 50 users at launch, growing by invite only.
---
## where to look
| what you need | read | when |
|---|---|---|
| vision + values | docs/CONCEPT.md | onboarding, big picture, tone questions |
| interaction + UI decisions | docs/DESIGN.md | frontend, UX, feature work |
| entities + schema | docs/DATA-MODEL.md | backend, db, API work |
| what's decided vs open | docs/OPEN-QUESTIONS.md | before proposing anything new — always |
| versioned plan | docs/ROADMAP.md | scoping, prioritization |
| backend + API structure | docs/ARCHITECTURE.md | does not exist yet. create before v0 alpha. |
---
## locked — do not relitigate
**product**
- chronological feed only. no algorithm, no ranking, no engagement bait.
- no push notifications in v1.
- no DMs in v1.
- no analytics or tracking. zero. not even self-hosted.
- no federation UI. activitypub via fedify is in the stack, federation flag is OFF.
- no premium tier. no donor badges. no class hierarchy in the app.
- no manifesto, no political iconography on any user-facing surface.
- `is_event` flag on posts for bulletin board. not a separate entity.
2026-06-03 17:42:40 +00:00
- posters: anyone can post. three post types, single required tag: `event` | `fundraiser` | `current affairs` . auto-archives 1 day after `event_ends_at` . layout: 2-column grid, infinite scroll, paginated fetch.
2026-05-31 13:12:30 +00:00
- reactions: poster defines up to 5 emoji + open picker fallback. stored as user + post + emoji + timestamp.
- save/bookmark: optional, toggled by poster at compose. default off.
- story interactions: no replies. "witnessed" metadata only, private, 24h.
- comments: flat, chronological, on posts only.
2026-06-03 17:42:40 +00:00
- surveys: admin-only creation. multiple choice only. 36h expiry. injected as slot-1 feed card (not a real post), drops per-user after response. `/feedback` always has free text field regardless of active survey.
2026-05-31 13:12:30 +00:00
**ux**
- users should never be asked to understand anything instagram doesn't ask them to understand.
- onboarding: invite link → install → email + username → magic link → in.
- the activitypub layer is invisible to users, always.
**never use**
- firebase, meta SDKs, google analytics, cloudflare, amazon, github, stripe-as-primary.
---
## conditionally open
- **notifications**: off in v1. DM notifications only if DMs land in v2. never for feed activity.
- **DMs**: deferred to v2. three options on table. not decided.
- **federation**: flag off. may flip in v2/v3. UI stays invisible either way.
2026-06-03 13:56:12 +00:00
- **PWA**: fallback option to consider if run into problems with apple app store.
2026-05-31 13:12:30 +00:00
---
## stack (settled)
runtime: bun / framework: elysia / activitypub: fedify / db: sqlite (postgres-ready) /
2026-06-03 13:56:12 +00:00
storage: filesystem → s3-compatible / uploads: tus.io / mobile: flutter + go_router /
2026-05-31 13:12:30 +00:00
hosting: njalla VPS / proxy: nginx / process: systemd / forge: radicle / funding: liberapay
---
## tone + voice
- quiet, not precious.
- no manifestos. no "we believe in" statements.
- register: "eutopic is a quiet place for friends to share photos."
- corporate, activist, or startup-y copy is wrong.
- transparency about costs: fine. nagging: not.
---
## values (as constraints)
- anti-attention economy: check every feature decision against this.
- "the architecture is the belief" — values show in what's built and refused, not in copy.
2026-06-03 13:56:12 +00:00
- compromises (flutter/dart, app stores) are named honestly in the about/credits page.
2026-05-31 13:12:30 +00:00
---
## when in doubt
1. check OPEN-QUESTIONS.md before proposing anything. don't relitigate closed decisions.
2. check tone: would this copy sound corporate or activist? wrong register.
3. check values: does this feature serve attention extraction? if yes, refuse it.
4. don't invent answers to open questions. flag them instead.