# Opus Review

**Model:** claude-opus-4
**Generated:** 2026-03-04T12:00:00Z

---

## Overall Assessment

Well-structured plan that correctly identifies the three-layer architecture. 20 issues identified ranging from architectural concerns to implementation footguns.

## High-Priority Issues

### #2 Security: Localhost Binding Is Not Sufficient
Any local process can connect to port 6007. `godotiq_run` is destructive. Browser DNS rebinding attacks possible.
**Recommendation:** Generate session token on addon startup, require in handshake. At minimum, add Origin header check.

### #4 Session Manager Singleton Has Race Conditions
Two concurrent tool calls could both see `_bridge is None` and create two connections.
**Recommendation:** Use `asyncio.Lock` to serialize connection creation.

### #12 Missing Cleanup/Shutdown Hook
`close_bridge()` is never called when MCP server shuts down. WebSocket stays open, background task keeps running.
**Recommendation:** Integrate into server lifespan's finally block.

## Medium-Priority Issues

### #1 Websockets Version Inconsistency
Sprint spec says `>=12.0`, plan/interview says `>=14.0`. API imports differ between versions.
**Recommendation:** Pick one and update all documents.

### #3 Missing Config Schema for `server.addon_port`
`GodotIQConfig` has no `server` field. Plan says not to touch `config.py`.
**Recommendation:** Clarify Python side uses env var only.

### #5 Background `_listen_loop` Lifecycle
Task may die silently on unexpected exceptions, leaving pending futures unresolved.
**Recommendation:** Catch all exceptions, fail pending futures, set connected=False.

### #6 Tool Registration Architecture
Plan contradicts itself on whether `@mcp.tool()` is in `__init__.py` or individual files.
**Recommendation:** Clarify canonical location.

### #9 Screenshot Viewport Parameter is Dead Code
`viewport="game"` param accepted but runtime always uses `get_viewport()`.
**Recommendation:** Remove viewport param or implement routing.

### #11 Retry Logic Too Broad
`request_with_retry` catches all errors. Connection errors shouldn't retry.
**Recommendation:** Only retry on transient/retryable error codes.

### #13 EngineDebugger Buffer Limits
Large base64 screenshots may exceed debugger IPC buffer limits.
**Recommendation:** Test with 4K screenshots. Document fallback.

### #14 Missing Tool Annotations
Bridge tools have different characteristics than Phase 1 tools. `godotiq_run` is destructive.
**Recommendation:** Specify exact annotations per tool.

### #15 Test Coverage Gaps
Missing: concurrent requests, retry exhaustion, reconnection flow, malformed responses.
**Recommendation:** Add reconnection and retry exhaustion tests.

### #18 GDScript Missing Input Validation
Malformed requests (missing id/method) could crash editor plugin.
**Recommendation:** Validate JSON structure before dispatch.

## Low-Priority Issues

### #7 Peer ID Generation Not Specified
Plan describes peer dictionary but not how IDs are generated.

### #8 GDScript `_process()` Polling Every Frame
60 polls/second even when idle. Consider Timer for idle state.

### #10 `_peer_tcp` Cleanup Not Specified
Must remove from `_peer_tcp` when removing from `_peers`.

### #16 `tools/bridge/__init__.py` Already Exists
Listed as "create" but already exists with a docstring.

### #17 Missing WebSocket Import Error Handling
Cryptic error if websockets not installed. Add clear message.

### #19 No Protocol Versioning
No way to detect version mismatches between Python and addon.

### #20 Addon Directory Location Ambiguous
No installation instructions for copying addon to Godot project.
