eutopic/AGENTS.md

3.8 KiB
Raw Blame History

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.