# Sojorn Backend Architecture ## How Boundaries Are Enforced Sojorn's calm 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. --- ## 2. Consent: Conversation Requires Mutual Follow **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. **Calm 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.