Comprehensive code review findings: - 23 total findings (2 P1, 9 P2, 12 P3) - Key issues: UID mismatch in kq4_004_ogres_cottage, missing tests - Verdict: Ready with fixes
7.7 KiB
Code Review: PR 3 - "Stealth Cymbal"
Scope
- Branch: stealth-cymbal
- Base: master
- Files Changed: 86 files (~1576 insertions, ~230 deletions)
- Key Changes: KQ4 Room Navigator skill, UID repair tools, MCP interaction server, room scene updates
Review Team
- ✅ ce-correctness-reviewer - Logic errors, edge cases, state bugs
- ✅ ce-testing-reviewer - Coverage gaps, weak assertions, brittle tests
- ✅ ce-maintainability-reviewer - Coupling, complexity, naming, dead code
- ✅ ce-project-standards-reviewer - CLAUDE.md and AGENTS.md compliance
- ✅ ce-agent-native-reviewer - Agent-accessible design patterns
- ✅ ce-learnings-researcher - Past issues in docs/solutions/
P1 -- High
| # | File | Issue | Reviewer | Confidence | Route |
|---|---|---|---|---|---|
| 1 | scenes/kq4_004_ogres_cottage/kq4_004_ogres_cottage.tscn:46 |
UID mismatch - target UID for kq4_028_mine_entrance points to non-existent room | correctness | 75% | manual → downstream-resolver |
| 2 | scripts/mcp_interaction_server.gd |
No runtime tests for 80+ TCP command handlers (171KB script) | testing | 50% | manual → downstream-resolver |
P2 -- Moderate
| # | File | Issue | Reviewer | Confidence | Route |
|---|---|---|---|---|---|
| 3 | scenes/kq4_098_transitional_room/kq4_098_transitional_room.tscn |
Missing .uid companion file | correctness | 75% | manual → review-fixer |
| 4 | scripts/build_room_graph.py:184 |
_resolve_target_room returns None without explicit handling in callers |
correctness | 75% | safe_auto → review-fixer |
| 5 | tools/repair_uids.py:322 |
Code duplication in fix_stale_target with inconsistent error handling | correctness | 75% | safe_auto → review-fixer |
| 6 | tools/repair_uids.py |
No tests for file mutation operations (UID sync, target replacement) | testing | 75% | manual → downstream-resolver |
| 7 | scripts/build_room_graph.py |
No tests for BFS edge cases (disconnected components, malformed UIDs) | testing | 75% | manual → downstream-resolver |
| 8 | MainGame.gd, SetPiece_.gd |
No tests for signal emission logic and cursor action routing | testing | 50% | manual → downstream-resolver |
| 9 | SetPiece_.gd:mock_interact() |
Unnecessary indirection - duplicates _input() logic |
maintainability | 75% | gated_auto → downstream-resolver |
| 10 | SetPiece_.gd |
Unused entered/exited signals with unclear lab param |
maintainability | 75% | gated_auto → downstream-resolver |
| 11 | tools/kq4_room_navigator.py |
sys.path manipulation creates coupling | maintainability | 50% | gated_auto → downstream-resolver |
P3 -- Low
| # | File | Issue | Reviewer | Confidence | Route |
|---|---|---|---|---|---|
| 12 | MainGame.gd:13 |
get_current_room_name() returns empty string on failure - silent failure mode |
correctness | 50% | advisory → downstream-resolver |
| 13 | scripts/mcp_interaction_server.gd:42 |
Fixed 30-second timeout could mask real hangs | correctness | 50% | advisory → downstream-resolver |
| 14 | SetPiece_.gd:60 |
mock_interact() doesn't validate target room exists |
correctness | 50% | advisory → downstream-resolver |
| 15 | tools/kq4_room_navigator.py |
No tests for CLI tool | testing | 75% | advisory → human |
| 16 | MainGame.gd |
Placeholder comment in _ready() - dead code |
maintainability | 100% | advisory → human |
| 17 | MainGame.gd |
Commented-out code with typo - dead code | maintainability | 100% | advisory → human |
| 18 | scripts/mcp_interaction_server.gd |
Potentially incomplete implementation | maintainability | 50% | advisory → human |
| 19 | .opencode/skills/kq4-room-navigator/SKILL.md:38-41 |
Code block formatting changed from JSON to plain text | project-standards | 75% | advisory → human |
| 20 | tools/kq4_room_navigator.py |
Dataclass overhead for Mismatch in CLI tool | maintainability | 50% | advisory → human |
| 21 | .opencode/skills/kq4-room-navigator/SKILL.md |
Missing explicit retry guidance for _busy protocol |
agent-native | 75% | advisory → human |
| 22 | .opencode/skills/kq4-room-navigator/SKILL.md |
mock_interact vs mock_interaction typo in error messages |
agent-native | 75% | safe_auto → review-fixer |
| 23 | .opencode/skills/kq4-room-navigator/SKILL.md |
--navigate flag documented but not implemented in CLI |
agent-native | 50% | gated_auto → downstream-resolver |
Requirements Completeness
No plan document found for this PR. The PR title "Stealth Cymbal" is ambiguous and doesn't reference a specific plan.
Pre-existing Issues
None identified in this review.
Learnings & Past Solutions
No institutional learnings found. The docs/solutions/ directory does not exist in this repository. Consider using /ce-compound skill after significant work to document:
- UID generation patterns (make_uid.py + .uid files)
- Navigation/pathfinding setup (NavigationServer2D)
- MCP server integration learnings
- Room transition wiring patterns
Agent-Native Gaps
- Offline-Only Graph Discovery - Agents can't dynamically discover room connectivity at runtime
- Manual Verification - Navigation completion requires polling instead of signals
- No Path Validation - Agents can attempt invalid navigation without guardrails
- Incomplete CLI - The
--navigateflag is documented but not implemented
Residual Risks
-
UID mismatch risk - Room graph connectivity depends on UID consistency across all .tscn and .uid files. If UIDs drift from manual edits, pathfinding will fail even though runtime transitions work.
- Mitigation: Run
tools/repair_uids.py --fixbefore each significant room update. Consider integrating UID validation into CI pipeline.
- Mitigation: Run
-
Timeout risk - The MCP server's
_busyflag uses a fixed 30-second timeout. If navigation animations or other operations take longer, commands may be prematurely reset.- Mitigation: Monitor
_busytimeout warnings in logs. Consider making configurable or implementing per-command timeout overrides.
- Mitigation: Monitor
-
Arbitrary code execution - MCP eval command allows arbitrary code execution without guardrails.
-
Heuristic risk - UID auto-resolution in repair_uids.py may produce incorrect fixes based on heuristics.
Testing Gaps
- No automated tests for UID consistency across room transitions
- No tests for pathfinding edge cases (disconnected rooms, single-room graphs, self-loops)
- No tests for MCP server command timeout behavior under load
- No validation that all TransitionPiece targets point to existing rooms
- No unit tests for UID mismatch detection in repair_uids.py
- No tests for BFS pathfinding edge cases in build_room_graph.py
- No tests for SetPiece signal emission logic
- No tests for busy-state timeout recovery in MCP server
Coverage
- Findings: 23 total (2 P1, 9 P2, 12 P3)
- Safe-auto (fixable now): 3 findings
- Manual (needs handoff): 4 findings
- Gated-auto (needs review): 4 findings
- Advisory (report-only): 12 findings
- Failed reviewers: 0 of 6
Verdict
Ready with fixes
Fix order:
- Critical: Fix UID mismatch in kq4_004_ogres_cottage.tscn (finding #1) - this breaks navigation
- High: Add missing .uid file for kq4_098_transitional_room (finding #3)
- Medium: Fix None handling in build_room_graph.py (finding #4)
- Medium: Consolidate code duplication in repair_uids.py (finding #5)
- Low: Address dead code and formatting issues (findings #12-23)
Before merge: Run tools/repair_uids.py --fix to synchronize all UIDs and verify the UID mismatch is resolved.