sojorn/sojorn_docs/archive/ARCHITECTURE.md

6 KiB

Sojorn Backend Architecture

How Boundaries Are Enforced

Sojorn's friendliness is not aspirational—it is structural. The database itself enforces the behavioral philosophy through Row Level Security (RLS), constraints, and functions that make certain behaviors impossible, not just discouraged.


1. Blocking: Complete Disappearance

Principle: When you block someone, they disappear from your world and you from theirs.

Implementation:

  • The has_block_between(user_a, user_b) function checks if either user has blocked the other.
  • RLS policies prevent blocked users from:
    • Seeing each other's profiles
    • Seeing each other's posts
    • Seeing each other's follows
    • Interacting in any way

Effect: No notifications, no traces, no conflict. The system enforces separation silently.


Principle: You cannot reply to someone unless you mutually follow each other.

Implementation:

  • The is_mutual_follow(user_a, user_b) function verifies bidirectional following.
  • Comments can only be created if is_mutual_follow(commenter, post_author) returns true.
  • RLS policies prevent reading comments unless you are:
    • The post author, OR
    • A mutual follower of the post author

Effect: Unwanted replies are impossible. Conversation is opt-in by structure.


3. Exposure: Opt-In by Default

Principle: Users choose what content they see. Filtering is private and encouraged.

Implementation:

  • All categories except general have default_off = true.
  • Users must explicitly enable categories to see posts from them.
  • RLS policies on posts check:
    • User has enabled the category, OR
    • Category is not default-off AND user hasn't disabled it

Effect: Heavy topics (grief, struggle, world events) are invisible unless invited in. No algorithmic exposure.


4. Influence: Earned Slowly Through Trust

Principle: New users have limited reach and posting capacity. Trust grows with positive behavior.

Implementation:

  • Each user has a trust_state with:
    • harmony_score (0-100, starts at 50)
    • tier (new, trusted, established, restricted)
    • Behavioral counters
  • Post rate limits depend on tier:
    • New: 3 posts/day
    • Trusted: 10 posts/day
    • Established: 25 posts/day
    • Restricted: 1 post/day
  • The can_post(user_id) function enforces this before allowing inserts.

Effect: Spam and abuse are throttled by friction. Positive contributors gain capacity over time.


5. Moderation: Guidance Through Friction, Not Punishment

Principle: Sharp speech does not travel. The system gently contains hostility.

Implementation:

  • Posts and comments carry tone_label and cis_score (content integrity score).
  • Content flagged as hostile:
    • Has reduced reach (implemented in feed algorithms, not yet built)
    • May be soft-deleted (status = 'removed')
    • Triggers adjustments to author's harmony_score
  • All moderation actions are logged in audit_log with full transparency.

Effect: Hostility is contained, not amplified. Violators experience reduced reach before account action.


6. Non-Attachment: Nothing Is Permanent

Principle: Feeds rotate, trends fade, attention is non-possessive.

Implementation:

  • No "permanence" affordances like pinned posts or evergreen content.
  • Posts are timestamped and will naturally age out of feeds.
  • No edit history preserved beyond edited_at timestamp.
  • Soft deletes allow content to disappear without breaking audit trails.

Effect: The platform discourages attachment to metrics or viral moments. Content is transient by design.


7. Transparency: Users Are Told How Reach Works

Principle: The system does not hide how it operates.

Implementation:

  • trust_state is visible to the user (their own state only via RLS).
  • audit_log events related to a user are readable by that user.
  • Rate limits, tier effects, and category mechanics are explained in-app (not yet built).

Effect: Users understand why their reach changes. No hidden algorithmic manipulation.


Database Design Summary

Core Tables

  • profiles: User identity (handle, display name, bio)
  • categories: Content organization with opt-in/opt-out controls
  • user_category_settings: Per-user category preferences
  • follows: Explicit connections (required for conversation)
  • blocks: Complete bidirectional separation

Content Tables

  • posts: Primary content (500 char max, categorized, moderated)
  • post_metrics: Engagement counters (likes, saves, views)
  • post_likes: Public appreciation (boosts)
  • post_saves: Private bookmarks
  • comments: Conversation within mutual-follow circles
  • comment_votes: Helpful/unhelpful signals (private)

Moderation Tables

  • reports: User-filed reports for review
  • trust_state: Per-user trust metrics and rate limits
  • audit_log: Complete transparency trail

Key Functions

  • has_block_between(user_a, user_b): Check for blocking
  • is_mutual_follow(user_a, user_b): Verify mutual connection
  • can_post(user_id): Rate limit enforcement
  • adjust_harmony_score(user_id, delta, reason): Trust adjustments
  • log_audit_event(actor_id, event_type, payload): Audit logging

What This Enables

  1. Friendliness is enforced, not suggested. The database will not allow hostile interactions.
  2. Boundaries are private. Blocking and filtering leave no trace visible to the blocked party.
  3. Consent is required. You cannot force your words into someone's space.
  4. Exposure is controlled. Users see only what they choose to see.
  5. Influence is earned. New accounts cannot spam or brigade.
  6. Moderation is transparent. Users know why their reach changed.

Next Steps

  • Edge Functions: Implement feed generation, content moderation, and signup flows.
  • Flutter Client: Build UI that reflects these structural constraints.
  • Content Moderation: Integrate tone classification and integrity scoring.
  • Feed Algorithms: Design reach curves based on harmony score and engagement patterns.