## 2026-10-02T02:46:48Z

You are Worker M3 (teamwork_preview_worker) implementing Milestone 3: Friend List & Social Engine for FreeExile.
Working Directory: c:\Projects\FreeExile\.agents\teamwork\worker_m3
Parent Conversation ID: 914399d4-059b-422e-a9e6-44e1005de38a

MANDATORY FIRST STEP:
Read:
- c:\Projects\FreeExile\.agents\teamwork\ORIGINAL_REQUEST.md (specifically ## 2026-10-02T02:12:28Z)
- c:\Projects\FreeExile\PROJECT.md
- c:\Projects\FreeExile\TEST_READY.md
- c:\Projects\FreeExile\.agents\teamwork\explorer_survey_2\survey_report.md
- c:\Projects\FreeExile\.agents\teamwork\worker_m1\handoff.md

MANDATORY INTEGRITY WARNING:
DO NOT CHEAT. All implementations must be genuine. DO NOT hardcode test results, create dummy/facade implementations, or circumvent the intended task. A teamwork_preview_auditor will independently verify your work. Integrity violations WILL be detected and your work WILL be rejected.

YOUR WRITE OWNERSHIP:
You own exclusively:
- `server/social/social_types.py`
- `server/social/social_repository.py`
- `server/social/social_service.py`
- `server/social/guild_roster_service.py`
- `server/social/__init__.py`
- `tests/unit/test_social_service.py`

YOUR TASKS:
1. Implement `server/social/social_types.py`:
   - `FriendshipStatus` enum: `NONE`, `PENDING_SENT`, `PENDING_RECEIVED`, `ACCEPTED`, `BLOCKED`
   - `PresenceStatus` enum: `OFFLINE`, `ONLINE`, `IN_COMBAT`, `AWAY`
   - `FriendDTO` (@dataclass(slots=True, frozen=True): player_id, character_name, level, character_class, presence_status, zone_id, current_map_name, friend_note, last_seen_timestamp)
   - `SocialActionResponse` (@dataclass(slots=True, frozen=True): success: bool, message: str, action_code: str)
   - `GuildMemberPresenceDTO` (@dataclass(slots=True, frozen=True): player_id, character_name, role: str, level: int, presence_status: PresenceStatus, zone_id: str, is_teleport_targetable: bool)
2. Implement `server/social/social_repository.py`:
   - SQLite persistence layer (using `data/social_store.db` or table `player_friendships` in database).
   - Normalized table: `player_friendships (user_id TEXT, friend_id TEXT, status TEXT, friend_note TEXT, created_at REAL, updated_at REAL, PRIMARY KEY (user_id, friend_id))`.
   - Index on `(user_id, status)` and `(friend_id, status)`.
   - Methods: `add_friend_request`, `accept_friend_request`, `decline_friend_request`, `remove_friend`, `block_player`, `unblock_player`, `get_friends`, `get_blocked_list`, `set_friend_note`, `is_friend`, `is_blocked`.
3. Implement `server/social/social_service.py`:
   - Complete friend lifecycle: send request, accept, decline, remove, block, unblock, set note.
   - Mutual block verification: if player A blocks player B, B cannot send friend request or whisper to A.
   - Synchronize with `server/chat/channel_manager.py._player_blacklists` when player is blocked/unblocked.
   - Real-time status sync: `update_player_presence(player_id, level, zone_id, presence_status)`.
   - Retrieve friend list with live presence info.
4. Implement `server/social/guild_roster_service.py`:
   - Integrates with `GuildMember` from `server/trade/guild_stash_service.py`.
   - Joins guild membership with real-time player presence to expose `get_guild_roster_with_presence(guild_id: str) -> List[GuildMemberPresenceDTO]`.
   - Teleport targetability: True if online and not in restricted private zone.
5. Create comprehensive unit tests in `tests/unit/test_social_service.py`.
6. Adhere strictly to GEMINI.md: all files <= 350 lines (hard cap 500), strictly typed, memory efficient.
7. Verification:
   - `pytest tests/unit/test_social_service.py -v`
   - `pytest tests/e2e_social_party/test_tier1_social_and_teleport.py -k "friend or social or guild" -v`
   - `pytest tests/e2e_social_party/ -v`
   - `python tools/lint/check_code_and_doc_hygiene.py --strict`
8. Write handoff to `c:\Projects\FreeExile\.agents\teamwork\worker_m3\handoff.md`.
Send message to parent when done.
