eutopic/AGENTS.md

90 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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: 550 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.
- 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.
- 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.
- 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.
**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.
- **PWA**: fallback option to consider if run into problems with apple app store.
---
## stack (settled)
runtime: bun / framework: elysia / activitypub: fedify / db: sqlite (postgres-ready) /
storage: filesystem → s3-compatible / uploads: tus.io / mobile: flutter + go_router /
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.
- compromises (flutter/dart, app stores) are named honestly in the about/credits page.
---
## 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.