- Created IT-08-SCREENSHOT-COMPLETION.md detailing the implementation of the Screenshot RPC, including technical summary, testing results, design decisions, and future work. - Introduced IT-10-COLLABORATIVE-EDITING.md outlining the vision, user stories, architecture, implementation plan, and success metrics for real-time collaborative editing in YAZE.
28 KiB
IT-10: Collaborative Editing & Multiplayer Sessions
Priority: P2 (High value, non-blocking)
Status: 📋 Planned
Estimated Effort: 12-15 hours
Dependencies: IT-05 (Test Introspection), IT-08 (Screenshot Capture)
Target: Enable real-time collaborative ROM editing with AI assistance
Vision
Enable multiple users to connect to the same YAZE session, see each other's edits in real-time, and collaborate with AI agents together. Think "Google Docs for ROM hacking" where users can:
- Connect to each other's sessions over the network
- See real-time edits (tiles, sprites, map changes)
- Share AI assistance (one user asks AI, all users see results)
- Coordinate workflows (e.g., one user edits dungeons, another edits overworld)
- Review changes together with live cursors and annotations
User Stories
US-1: Session Host & Join
As a ROM hacker, I want to host a collaborative editing session so my teammates can join and work together.
# Host creates a session
$ z3ed collab host --port 5000 --password "dev123"
✅ Collaborative session started
Session ID: yaze-collab-f3a9b2c1
URL: yaze://connect/localhost:5000?session=yaze-collab-f3a9b2c1
Password: dev123
👥 Waiting for collaborators...
# Remote user joins
$ z3ed collab join yaze://connect/192.168.1.100:5000?session=yaze-collab-f3a9b2c1
🔐 Enter session password: ***
✅ Connected to session (Host: Alice)
👥 Active users: Alice (host), Bob (you)
Acceptance Criteria:
- Host can create session with optional password
- Clients can discover and join sessions
- Connection state visible in GUI status bar
- Maximum 8 concurrent users per session
US-2: Real-Time Edit Synchronization
As a collaborator, I want to see other users' edits in real-time so we stay synchronized.
Scenario: Alice edits a tile in Overworld Editor
Alice's GUI:
- Draws tile at (10, 15) → Sends edit event to all clients
Bob's GUI (auto-update):
- Receives edit event → Redraws tile at (10, 15)
- Shows Alice's cursor/selection indicator
Acceptance Criteria:
- Edits appear on all clients within 100ms
- Conflict resolution for simultaneous edits
- Undo/redo synchronized across sessions
- Cursor positions visible for all users
US-3: Shared AI Agent
As a team lead, I want to use AI agents with my team so we can all benefit from automation.
# Alice (host) runs an AI agent test
$ z3ed agent test --prompt "Add treasure chest to room 12" --share
🤖 AI Agent: Analyzing request...
Action: Click "Dungeon Editor" tab
Action: Select Room 12
Action: Add object type 0x12 (treasure chest) at (5, 8)
✅ Proposal generated (ID: prop_3f8a)
# All connected users see the proposal in their GUI
Bob's Screen:
┌─────────────────────────────────────────┐
│ 🤖 AI Proposal from Alice │
│ │
│ Add treasure chest to room 12 │
│ • Click "Dungeon Editor" tab │
│ • Select Room 12 │
│ • Add treasure chest at (5, 8) │
│ │
│ [Accept] [Reject] [Discuss] │
└─────────────────────────────────────────┘
# Team vote: 2/3 accept → Proposal executes for all users
Acceptance Criteria:
- AI agent results broadcast to all session members
- Proposals require majority approval (configurable threshold)
- All users see agent execution in real-time
- Failed operations rollback for all users
US-4: Live Cursors & Annotations
As a collaborator, I want to see where other users are working so we don't conflict.
Visual Indicators:
┌─────────────────────────────────────────────┐
│ Overworld Editor │
│ │
│ 🟦 (Alice's cursor at map 0x40) │
│ 🟩 (Bob's cursor at map 0x41) │
│ 🟥 (Charlie editing palette) │
│ │
│ Active Editors: │
│ • Alice: Overworld (read-write) │
│ • Bob: Overworld (read-write) │
│ • Charlie: Palette Editor (read-only) │
└─────────────────────────────────────────────┘
Acceptance Criteria:
- Each user has unique color-coded cursor
- Active editor window highlighted for each user
- Text chat overlay for quick communication
- Annotation tools (pins, comments, highlights)
US-5: Session Recording & Replay
As a project manager, I want to record collaborative sessions so we can review work later.
# Host enables session recording
$ z3ed collab host --record session_2025_10_02.yaml
# Recording captures:
# - All edit operations (tiles, sprites, maps)
# - AI agent proposals and votes
# - Chat messages and annotations
# - User join/leave events
# - Timestamps for audit trail
# Later: Replay the session
$ z3ed collab replay session_2025_10_02.yaml --speed 2x
# Replay shows:
# - Timeline of all edits
# - User activity heatmap
# - Decision points (proposals accepted/rejected)
# - Final ROM state comparison
Acceptance Criteria:
- All session activity recorded in structured format (YAML/JSON)
- Replay supports speed control (0.5x - 10x)
- Export to video format (optional, uses screenshots)
- Audit log for compliance/review
Architecture
Components
1. Collaboration Server (New)
Location: src/app/core/collab/collab_server.{h,cc}
Responsibilities:
- Manage WebSocket connections from clients
- Broadcast edit events to all connected clients
- Handle session authentication (password, tokens)
- Enforce access control (read-only vs read-write)
- Maintain session state (active users, current ROM)
Technology:
- WebSocket for low-latency bidirectional communication
- Protocol Buffers for efficient serialization
- JWT tokens for session authentication
- Redis (optional) for distributed sessions
Key APIs:
class CollabServer {
public:
// Start server on specified port
absl::Status Start(int port, const std::string& password);
// Handle new client connection
void OnClientConnected(ClientConnection* client);
// Broadcast edit event to all clients
void BroadcastEdit(const EditEvent& event, ClientConnection* sender);
// Handle AI proposal from client
void BroadcastProposal(const AgentProposal& proposal);
// Get active users in session
std::vector<UserInfo> GetActiveUsers() const;
private:
std::unique_ptr<WebSocketServer> ws_server_;
absl::Mutex clients_mutex_;
std::vector<std::unique_ptr<ClientConnection>> clients_;
SessionState session_state_;
};
2. Collaboration Client (New)
Location: src/app/core/collab/collab_client.{h,cc}
Responsibilities:
- Connect to remote collaboration server
- Send local edits to server
- Receive and apply remote edits
- Sync ROM state on join
- Handle disconnection/reconnection
Key APIs:
class CollabClient {
public:
// Connect to session
absl::Status Connect(const std::string& url, const std::string& password);
// Send local edit to server
void SendEdit(const EditEvent& event);
// Callback when remote edit received
void OnRemoteEdit(const EditEvent& event);
// Get list of active users
std::vector<UserInfo> GetUsers() const;
// Disconnect from session
void Disconnect();
private:
std::unique_ptr<WebSocketClient> ws_client_;
CollabEventHandler* event_handler_;
SessionInfo session_info_;
};
3. Edit Event Protocol (New)
Location: src/app/core/proto/collab_events.proto
Message Definitions:
syntax = "proto3";
package yaze.collab;
// Generic edit event
message EditEvent {
string event_id = 1; // Unique event ID
string user_id = 2; // User who made the edit
int64 timestamp_ms = 3; // Unix timestamp
oneof event_type {
TileEdit tile_edit = 10;
SpriteEdit sprite_edit = 11;
PaletteEdit palette_edit = 12;
MapEdit map_edit = 13;
ObjectEdit object_edit = 14;
}
}
// Tile edit (Tile16 Editor, Tilemap)
message TileEdit {
string editor = 1; // "tile16", "tilemap"
int32 x = 2;
int32 y = 3;
int32 layer = 4;
bytes tile_data = 5; // Tile pixel data or ID
}
// Sprite edit
message SpriteEdit {
int32 sprite_id = 1;
int32 x = 2;
int32 y = 3;
bytes sprite_data = 4;
}
// Map edit (Overworld/Dungeon)
message MapEdit {
string map_type = 1; // "overworld", "dungeon"
int32 map_id = 2;
bytes map_data = 3;
}
// User cursor position
message CursorEvent {
string user_id = 1;
string editor = 2; // Active editor window
int32 x = 3;
int32 y = 4;
string color = 5; // Cursor color (hex)
}
// AI proposal event
message ProposalEvent {
string proposal_id = 1;
string user_id = 2; // User who initiated agent
string prompt = 3;
repeated ProposalAction actions = 4;
enum ProposalStatus {
PENDING = 0;
ACCEPTED = 1;
REJECTED = 2;
EXECUTING = 3;
COMPLETED = 4;
}
ProposalStatus status = 5;
// Voting
map<string, bool> votes = 6; // user_id -> accept/reject
int32 votes_needed = 7;
}
message ProposalAction {
string action_type = 1; // "click", "type", "edit"
map<string, string> params = 2;
}
// Session state
message SessionState {
string session_id = 1;
string host_user_id = 2;
repeated UserInfo users = 3;
bytes rom_checksum = 4; // SHA256 of ROM
int64 session_start_ms = 5;
}
message UserInfo {
string user_id = 1;
string username = 2;
string color = 3; // User's cursor color
bool is_host = 4;
bool read_only = 5;
string active_editor = 6;
}
4. Conflict Resolution System
Challenge: Multiple users edit the same tile/sprite simultaneously
Solution: Operational Transformation (OT) with timestamps
class ConflictResolver {
public:
// Resolve conflicting edits
EditEvent ResolveConflict(const EditEvent& local,
const EditEvent& remote);
private:
// Last-write-wins with timestamp
EditEvent LastWriteWins(const EditEvent& e1, const EditEvent& e2);
// Merge edits if possible (e.g., different layers)
std::optional<EditEvent> TryMerge(const EditEvent& e1,
const EditEvent& e2);
};
Conflict Resolution Rules:
- Same tile, different times: Last write wins (based on timestamp)
- Same tile, same time (<100ms): Host user wins (host authority)
- Different tiles: No conflict, apply both
- Different layers: No conflict, apply both
- Undo/Redo: Undo takes precedence (explicit user intent)
5. GUI Integration
Status Bar Indicator:
┌─────────────────────────────────────────────────────────────┐
│ File Edit View Tools Help 👥 3 users connected │
│ 🟢 Alice (Host) │
│ 🔵 Bob │
│ 🟣 Charlie │
└─────────────────────────────────────────────────────────────┘
Collaboration Panel:
┌─────────────────────────────────┐
│ Collaboration │
├─────────────────────────────────┤
│ Session: yaze-collab-f3a9b2c1 │
│ Status: 🟢 Connected │
│ │
│ Users (3): │
│ 🟢 Alice (Host) - Dungeon │
│ 🔵 Bob (You) - Overworld │
│ 🟣 Charlie - Palette │
│ │
│ Activity: │
│ • Alice edited room 12 │
│ • Bob added sprite #23 │
│ • Charlie changed palette 2 │
│ │
│ [Chat] [Proposals] [Disconnect] │
└─────────────────────────────────┘
Cursor Overlay:
// In canvas rendering
void OverworldCanvas::DrawCollaborativeCursors() {
for (const auto& user : collab_client_->GetUsers()) {
if (user.active_editor == "overworld" && user.user_id != my_user_id) {
ImVec2 cursor_pos = TileToScreen(user.cursor_x, user.cursor_y);
ImU32 color = ImGui::GetColorU32(user.color);
// Draw cursor indicator
draw_list->AddCircleFilled(cursor_pos, 5.0f, color);
// Draw username label
draw_list->AddText(cursor_pos + ImVec2(10, -5), color, user.username.c_str());
}
}
}
CLI Commands
Session Management
# Host a session
z3ed collab host [options]
--port <port> Port to listen on (default: 5000)
--password <password> Session password (optional)
--max-users <n> Maximum concurrent users (default: 8)
--read-only <users> Comma-separated list of read-only users
--record <file> Record session to file
# Join a session
z3ed collab join <url> [options]
--password <password> Session password
--username <name> Display name (default: system username)
--read-only Join in read-only mode
# List active sessions (LAN discovery)
z3ed collab list
# Disconnect from session
z3ed collab disconnect
# Kick user (host only)
z3ed collab kick <user-id>
Session Replay
# Replay recorded session
z3ed collab replay <file> [options]
--speed <n> Playback speed multiplier (default: 1.0)
--start-time <time> Start at specific timestamp
--end-time <time> End at specific timestamp
--export-video <file> Export to video (requires ffmpeg)
# Export session timeline
z3ed collab export <file> [options]
--format <format> Output format: json, yaml, csv (default: json)
--include-chat Include chat messages
--include-proposals Include AI proposals
Implementation Plan
Phase 1: Core Networking (4-5 hours)
Tasks:
- Set up WebSocket server (using
libwebsocketsorBoost.Beast) - Implement client connection handling
- Define
EditEventprotobuf messages - Implement basic message routing (send/receive)
- Test with 2 clients: edit on one, see on other
Deliverables:
collab_server.{h,cc}with basic WebSocket handlingcollab_client.{h,cc}with connection managementcollab_events.protowith edit event definitions
Validation:
- Client A connects to host
- Client A sends test edit event
- Host receives and broadcasts to Client B
- Client B receives edit event
Phase 2: Edit Synchronization (3-4 hours)
Tasks:
- Hook into editor event system (Overworld, Dungeon, Tile16, Palette)
- Capture local edits and convert to
EditEventmessages - Apply remote
EditEventmessages to local ROM - Implement conflict resolution (last-write-wins)
- Add undo/redo synchronization
Deliverables:
- Edit event capture hooks in all editors
- Edit event application logic
- Conflict resolver implementation
Validation:
- User A edits tile → User B sees tile change
- User A edits palette → User B sees palette change
- Simultaneous edits resolve correctly (no data corruption)
Phase 3: GUI Integration (2-3 hours)
Tasks:
- Add status bar indicator (connected users count)
- Create Collaboration panel (ImGui window)
- Implement live cursor rendering
- Add user color assignment (unique per user)
- Display active editor for each user
Deliverables:
- Status bar widget showing connection status
- Collaboration panel showing user list and activity
- Cursor overlay in canvas editors
Validation:
- User can see who's connected
- User can see other users' cursor positions
- User can see what editor others are using
Phase 4: AI Agent Sharing (2-3 hours)
Tasks:
- Broadcast AI proposals to all session members
- Implement proposal voting system (majority rule)
- Synchronize agent execution across clients
- Handle proposal rejection/timeout
- Add proposal history to Collaboration panel
Deliverables:
ProposalEventprotobuf messages- Voting UI in GUI (Accept/Reject/Discuss buttons)
- Proposal broadcast and execution logic
Validation:
- User A runs agent → All users see proposal
- Users vote on proposal → Executes if majority accepts
- Proposal execution synchronized (all users see same result)
Phase 5: Session Recording & Replay (1-2 hours)
Tasks:
- Implement session recorder (capture all events to file)
- Create replay engine (read events from file, re-apply)
- Add timeline UI for replay (seek, pause, speed control)
- Export session to JSON/YAML for analysis
Deliverables:
session_recorder.{h,cc}with file I/Osession_player.{h,cc}with playback control- CLI commands for replay
Validation:
- Record session → All events captured
- Replay session → ROM state matches original
- Seek/speed control works correctly
Security & Safety Considerations
Authentication
Password Protection:
- Session host sets optional password
- Clients must provide password to join
- Passwords hashed with bcrypt (never transmitted in plaintext)
Token-Based Auth (Future):
- Host generates JWT tokens for trusted users
- Tokens expire after session ends
- Revocation list for kicked users
Authorization
Access Levels:
- Host: Full control (read-write, kick users, end session)
- Editor: Read-write access to ROM
- Viewer: Read-only access (can see edits, can't make edits)
Permission Model:
enum class AccessLevel {
kHost, // Full control
kEditor, // Read-write
kViewer // Read-only
};
class SessionPermissions {
public:
bool CanEdit(const std::string& user_id) const;
bool CanKick(const std::string& user_id) const;
bool CanEndSession(const std::string& user_id) const;
void SetAccessLevel(const std::string& user_id, AccessLevel level);
};
Data Integrity
ROM Checksum Verification:
- Host broadcasts ROM checksum (SHA256) on session start
- Clients verify their ROM matches host's ROM
- Mismatched ROMs rejected (prevents desyncs)
Edit Validation:
- Server validates edit events before broadcasting
- Invalid edits rejected (e.g., out-of-bounds tile index)
- Clients trust server's validation (reduces client-side checks)
Network Security
Encryption (Optional, for public internet sessions):
- Use WSS (WebSocket Secure) with TLS/SSL
- Self-signed certificates for LAN (trust on first use)
- Let's Encrypt certificates for public servers
Rate Limiting:
- Max 100 edit events per second per user
- Max 10 AI proposals per minute per session
- Prevents spam/DOS attacks
Testing Strategy
Unit Tests
Conflict Resolution:
TEST(ConflictResolverTest, LastWriteWins) {
ConflictResolver resolver;
EditEvent e1 = MakeTileEdit(10, 15, /*timestamp=*/1000);
EditEvent e2 = MakeTileEdit(10, 15, /*timestamp=*/2000);
EditEvent resolved = resolver.ResolveConflict(e1, e2);
EXPECT_EQ(resolved.timestamp_ms(), 2000); // e2 wins
}
TEST(ConflictResolverTest, MergeDifferentLayers) {
ConflictResolver resolver;
EditEvent e1 = MakeTileEdit(10, 15, /*layer=*/0, /*timestamp=*/1000);
EditEvent e2 = MakeTileEdit(10, 15, /*layer=*/1, /*timestamp=*/1000);
auto merged = resolver.TryMerge(e1, e2);
ASSERT_TRUE(merged.has_value());
// Both edits should be applied (different layers)
}
Integration Tests
Session Connection:
TEST(CollabServerTest, ClientConnection) {
CollabServer server;
server.Start(5000, "password123");
CollabClient client;
auto status = client.Connect("ws://localhost:5000", "password123");
EXPECT_TRUE(status.ok());
EXPECT_EQ(server.GetActiveUsers().size(), 1);
}
TEST(CollabServerTest, EditBroadcast) {
CollabServer server;
server.Start(5000, "password123");
CollabClient client1, client2;
client1.Connect("ws://localhost:5000", "password123");
client2.Connect("ws://localhost:5000", "password123");
// Client 1 sends edit
EditEvent edit = MakeTileEdit(10, 15, 1000);
client1.SendEdit(edit);
// Wait for broadcast
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Client 2 should receive edit
EXPECT_TRUE(client2.HasReceivedEdit(edit.event_id()));
}
E2E Tests
Collaborative Workflow:
#!/bin/bash
# tests/e2e/test_collab_workflow.sh
# Start host in background
z3ed collab host --port 5000 --password test &
HOST_PID=$!
sleep 2
# Client 1 joins
z3ed collab join ws://localhost:5000 --password test --username Alice &
CLIENT1_PID=$!
sleep 1
# Client 2 joins
z3ed collab join ws://localhost:5000 --password test --username Bob &
CLIENT2_PID=$!
sleep 1
# Verify 3 users connected (host + 2 clients)
USERS=$(z3ed collab users --json | jq '. | length')
if [ "$USERS" -ne 3 ]; then
echo "❌ Expected 3 users, got $USERS"
exit 1
fi
# Client 1 makes edit via CLI
z3ed project overworld edit --map 0x40 --tile-x 10 --tile-y 15 --tile-id 0x123
# Wait for sync
sleep 0.5
# Verify edit appeared on Client 2
TILE_ID=$(z3ed project overworld get --map 0x40 --tile-x 10 --tile-y 15 --json | jq '.tile_id')
if [ "$TILE_ID" != "0x123" ]; then
echo "❌ Edit not synchronized"
exit 1
fi
echo "✅ Collaborative workflow test passed"
# Cleanup
kill $HOST_PID $CLIENT1_PID $CLIENT2_PID
Performance Considerations
Bandwidth Usage
Typical Edit Event Size:
- TileEdit: ~50 bytes (protobuf encoded)
- CursorEvent: ~30 bytes
- ProposalEvent: ~500 bytes (with actions)
Estimated Bandwidth (3 users, moderate activity):
- Edit events: 10/sec × 50 bytes = 500 bytes/sec
- Cursor updates: 30/sec × 30 bytes = 900 bytes/sec
- Total: ~1.4 KB/sec per client (~11 Kbps)
Optimization:
- Batch cursor updates (send every 50ms instead of every frame)
- Delta compression for tile data (send only changed pixels)
- Message prioritization (edits > cursors > chat)
Latency Targets
| Metric | Target | Acceptable | Critical |
|---|---|---|---|
| Edit propagation | <50ms | <100ms | >200ms |
| Cursor update | <16ms | <33ms | >100ms |
| Proposal broadcast | <100ms | <200ms | >500ms |
| Connection timeout | - | - | >5s |
Optimization Strategies:
- WebSocket for low-latency bidirectional communication
- Protobuf for efficient serialization (vs JSON)
- Message batching for cursor updates
- Predictive rendering (interpolate remote cursors)
Future Enhancements
Voice Chat Integration
Idea: Embed WebRTC voice chat for real-time communication
z3ed collab host --voice --voice-codec opus
Benefits:
- Faster coordination than text chat
- Enhances team collaboration
- Optional (users can disable if not needed)
Persistent Sessions
Idea: Sessions persist across host disconnects (using Redis)
Architecture:
┌──────────┐ ┌───────────┐ ┌──────────┐
│ Client A ├────►│ Redis │◄────┤ Client B │
└──────────┘ │ (session │ └──────────┘
│ state) │
┌──────────┐ │ │ ┌──────────┐
│ Client C ├────►│ │◄────┤ Client D │
└──────────┘ └───────────┘ └──────────┘
Benefits:
- Host can disconnect without ending session
- Any user can become new host (elected automatically)
- Session state preserved (users, edits, proposals)
Cloud-Hosted Sessions
Idea: Deploy collab server to cloud for public access
# Deploy to AWS/GCP/Azure
z3ed collab deploy --provider aws --region us-east-1
# Join cloud session
z3ed collab join wss://yaze-collab.example.com/session/abc123
Benefits:
- No port forwarding required
- Better uptime and reliability
- Centralized session management
Integration with Version Control
Idea: Auto-commit edits to Git during collaborative sessions
z3ed collab host --git-auto-commit --git-interval 5m
Behavior:
- Every 5 minutes, commit current ROM state to Git
- Commit message includes user activity summary
- Creates audit trail for rollback/review
Success Metrics
Adoption Metrics
- Active Sessions: 50+ concurrent sessions within 3 months
- User Retention: 60% of users who try collab use it again
- Session Duration: Average 30+ minutes per session
Technical Metrics
- Edit Latency: <100ms p99 (99th percentile)
- Uptime: >99.5% (excluding client disconnects)
- Conflict Rate: <1% of edits result in conflicts
- Bandwidth: <5 KB/sec per client average
User Satisfaction
- NPS Score: 40+ (Net Promoter Score)
- Bug Reports: <5 critical bugs per 1000 sessions
- Support Tickets: <10 per month related to collab features
Risks & Mitigation
Risk 1: Network Latency
Impact: High latency (>200ms) degrades user experience
Mitigation:
- Implement client-side prediction (apply edits immediately, rollback if rejected)
- Show latency indicator in GUI (yellow/red warning)
- Suggest LAN-only for high-latency users
Risk 2: Data Corruption
Impact: Conflicting edits corrupt ROM data
Mitigation:
- Validate all edits server-side before broadcasting
- Implement robust conflict resolution (last-write-wins with timestamps)
- Periodic checksum verification (every 60 seconds)
- Auto-save backups every 5 minutes (local + server)
Risk 3: Security Vulnerabilities
Impact: Malicious users could inject invalid edits or DOS the server
Mitigation:
- Rate limiting (100 edits/sec per user)
- Input validation (all edit events validated before broadcast)
- Optional authentication (password or JWT tokens)
- Audit logging (all events logged for forensics)
Risk 4: Scalability
Impact: Server struggles with 8+ concurrent users
Mitigation:
- Load testing with 20+ simulated users
- Message batching (reduce per-message overhead)
- Horizontal scaling with Redis (future enhancement)
- Hard cap at 8 users per session (prevents overload)
Summary
IT-10 brings real-time collaborative editing to YAZE, enabling teams to work together on ROM hacks with AI assistance. Key features:
✅ Session Hosting: Host collaborative sessions with password protection
✅ Real-Time Sync: Edits appear on all clients within 100ms
✅ Shared AI Agents: Team votes on AI proposals before execution
✅ Live Cursors: See where teammates are working
✅ Session Recording: Replay sessions for review and audit
Estimated Effort: 12-15 hours
Dependencies: IT-05 (Introspection), IT-08 (Screenshot Capture)
Priority: P2 (High value, but not blocking other work)
Recommended Timeline:
- After IT-09 Complete: Once CI/CD integration is done
- Before Agent Workflow (Phase A3): Collab enhances agent workflows (team AI usage)
Next Steps:
- Finalize IT-08 (Enhanced Error Reporting)
- Complete IT-09 (CI/CD Integration)
- Prototype collab server with 2-client test
- Gather user feedback on collaborative workflows
Document Created: October 2, 2025
Author: GitHub Copilot (AI Assistant)
Project: YAZE - Yet Another Zelda3 Editor
Component: z3ed CLI Tool - Collaborative Editing