robot_lab 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/.architecture/AGENTS.md +32 -0
  3. data/.architecture/config.yml +8 -0
  4. data/.architecture/members.yml +60 -0
  5. data/.architecture/reviews/feature-free-will.md +490 -0
  6. data/.architecture/reviews/overall-codebase.md +427 -0
  7. data/.claude/settings.local.json +57 -0
  8. data/.codex/config.toml +2 -0
  9. data/.irbrc +2 -2
  10. data/.rubocop.yml +172 -0
  11. data/CHANGELOG.md +72 -0
  12. data/CLAUDE.md +139 -0
  13. data/README.md +91 -95
  14. data/Rakefile +109 -3
  15. data/agent2agent_review.md +192 -0
  16. data/agentf_improvements.md +253 -0
  17. data/agents.md +14 -0
  18. data/docs/examples/index.md +37 -2
  19. data/docs/getting-started/configuration.md +20 -7
  20. data/docs/guides/index.md +16 -16
  21. data/docs/guides/knowledge.md +7 -1
  22. data/docs/guides/observability.md +132 -0
  23. data/docs/index.md +30 -3
  24. data/docs/superpowers/plans/2026-05-06-agentskills.md +1303 -0
  25. data/docs/superpowers/specs/2026-05-06-agentskills-design.md +247 -0
  26. data/examples/.envrc +1 -0
  27. data/examples/01_simple_robot.rb +5 -9
  28. data/examples/02_tools.rb +5 -9
  29. data/examples/03_network.rb +8 -9
  30. data/examples/04_mcp.rb +21 -29
  31. data/examples/05_streaming.rb +12 -18
  32. data/examples/06_prompt_templates.rb +11 -19
  33. data/examples/07_network_memory.rb +16 -31
  34. data/examples/08_llm_config.rb +10 -22
  35. data/examples/09_chaining.rb +16 -27
  36. data/examples/10_memory.rb +12 -28
  37. data/examples/11_network_introspection.rb +15 -29
  38. data/examples/12_message_bus.rb +5 -12
  39. data/examples/13_spawn.rb +5 -10
  40. data/examples/14_rusty_circuit/.envrc +1 -0
  41. data/examples/14_rusty_circuit/comic.rb +2 -0
  42. data/examples/14_rusty_circuit/heckler.rb +1 -1
  43. data/examples/14_rusty_circuit/open_mic.rb +1 -3
  44. data/examples/14_rusty_circuit/scout.rb +2 -0
  45. data/examples/15_memory_network_and_bus/.envrc +1 -0
  46. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +6 -3
  47. data/examples/15_memory_network_and_bus/linux_writer.rb +1 -1
  48. data/examples/15_memory_network_and_bus/output/combined_article.md +6 -6
  49. data/examples/15_memory_network_and_bus/output/final_article.md +6 -8
  50. data/examples/15_memory_network_and_bus/output/linux_draft.md +4 -2
  51. data/examples/15_memory_network_and_bus/output/mac_draft.md +3 -3
  52. data/examples/15_memory_network_and_bus/output/memory.json +6 -6
  53. data/examples/15_memory_network_and_bus/output/revision_1.md +10 -11
  54. data/examples/15_memory_network_and_bus/output/revision_2.md +6 -8
  55. data/examples/15_memory_network_and_bus/output/windows_draft.md +3 -3
  56. data/examples/16_writers_room/.envrc +1 -0
  57. data/examples/16_writers_room/writers_room.rb +2 -4
  58. data/examples/17_skills.rb +8 -17
  59. data/examples/18_rails/Gemfile +1 -0
  60. data/examples/19_token_tracking.rb +9 -15
  61. data/examples/20_circuit_breaker.rb +10 -19
  62. data/examples/21_learning_loop.rb +11 -20
  63. data/examples/22_context_compression.rb +6 -13
  64. data/examples/23_convergence.rb +6 -17
  65. data/examples/24_structured_delegation.rb +11 -15
  66. data/examples/25_history_search.rb +5 -12
  67. data/examples/26_document_store.rb +6 -13
  68. data/examples/27_incident_response/incident_response.rb +4 -5
  69. data/examples/28_mcp_discovery.rb +8 -11
  70. data/examples/29_ractor_tools.rb +4 -9
  71. data/examples/30_ractor_network.rb +10 -19
  72. data/examples/31_launch_assessment.rb +10 -23
  73. data/examples/32_newsletter_reader.rb +188 -0
  74. data/examples/33_stock_generator.rb +80 -0
  75. data/examples/33_stock_predictor.rb +306 -0
  76. data/examples/34_agentskills.rb +72 -0
  77. data/examples/README.md +1 -1
  78. data/examples/common.rb +76 -0
  79. data/examples/ruboruby.md +423 -0
  80. data/examples/temp.md +51 -0
  81. data/lib/robot_lab/agent_skill.rb +63 -0
  82. data/lib/robot_lab/agent_skill_catalog.rb +74 -0
  83. data/lib/robot_lab/ask_user.rb +2 -2
  84. data/lib/robot_lab/bus_poller.rb +12 -5
  85. data/lib/robot_lab/config.rb +1 -12
  86. data/lib/robot_lab/delegation_future.rb +1 -1
  87. data/lib/robot_lab/doom_loop_detector.rb +98 -0
  88. data/lib/robot_lab/history_compressor.rb +4 -10
  89. data/lib/robot_lab/mcp/client.rb +1 -2
  90. data/lib/robot_lab/mcp/connection_poller.rb +3 -3
  91. data/lib/robot_lab/mcp/server.rb +1 -1
  92. data/lib/robot_lab/mcp/server_discovery.rb +0 -2
  93. data/lib/robot_lab/memory.rb +32 -27
  94. data/lib/robot_lab/memory_change.rb +2 -2
  95. data/lib/robot_lab/message.rb +4 -4
  96. data/lib/robot_lab/network.rb +11 -6
  97. data/lib/robot_lab/robot/agent_skill_matching.rb +99 -0
  98. data/lib/robot_lab/robot/bus_messaging.rb +9 -27
  99. data/lib/robot_lab/robot/history_search.rb +4 -1
  100. data/lib/robot_lab/robot/mcp_management.rb +5 -11
  101. data/lib/robot_lab/robot/template_rendering.rb +60 -40
  102. data/lib/robot_lab/robot.rb +323 -206
  103. data/lib/robot_lab/robot_result.rb +6 -5
  104. data/lib/robot_lab/run_config.rb +5 -11
  105. data/lib/robot_lab/script_tool.rb +76 -0
  106. data/lib/robot_lab/state_proxy.rb +7 -5
  107. data/lib/robot_lab/tool.rb +3 -3
  108. data/lib/robot_lab/tool_config.rb +1 -1
  109. data/lib/robot_lab/tool_manifest.rb +5 -7
  110. data/lib/robot_lab/user_message.rb +2 -2
  111. data/lib/robot_lab/version.rb +1 -1
  112. data/lib/robot_lab/waiter.rb +1 -1
  113. data/lib/robot_lab.rb +41 -52
  114. data/logfile +8 -0
  115. data/mkdocs.yml +2 -3
  116. data/robot_concurrency.md +38 -0
  117. data/simple_acp_review.md +298 -0
  118. data/site/404.html +2300 -0
  119. data/site/api/core/index.html +2706 -0
  120. data/site/api/core/memory/index.html +3793 -0
  121. data/site/api/core/network/index.html +3500 -0
  122. data/site/api/core/robot/index.html +4566 -0
  123. data/site/api/core/state/index.html +3390 -0
  124. data/site/api/core/tool/index.html +3843 -0
  125. data/site/api/index.html +2635 -0
  126. data/site/api/mcp/client/index.html +3435 -0
  127. data/site/api/mcp/index.html +2783 -0
  128. data/site/api/mcp/server/index.html +3252 -0
  129. data/site/api/mcp/transports/index.html +3352 -0
  130. data/site/api/messages/index.html +2641 -0
  131. data/site/api/messages/text-message/index.html +3087 -0
  132. data/site/api/messages/tool-call-message/index.html +3159 -0
  133. data/site/api/messages/tool-result-message/index.html +3252 -0
  134. data/site/api/messages/user-message/index.html +3212 -0
  135. data/site/api/streaming/context/index.html +3282 -0
  136. data/site/api/streaming/events/index.html +3347 -0
  137. data/site/api/streaming/index.html +2738 -0
  138. data/site/architecture/core-concepts/index.html +3757 -0
  139. data/site/architecture/index.html +2797 -0
  140. data/site/architecture/message-flow/index.html +3238 -0
  141. data/site/architecture/network-orchestration/index.html +3433 -0
  142. data/site/architecture/robot-execution/index.html +3140 -0
  143. data/site/architecture/state-management/index.html +3498 -0
  144. data/site/assets/css/custom.css +56 -0
  145. data/site/assets/images/favicon.png +0 -0
  146. data/site/assets/images/robot_lab.jpg +0 -0
  147. data/site/assets/javascripts/bundle.79ae519e.min.js +16 -0
  148. data/site/assets/javascripts/bundle.79ae519e.min.js.map +7 -0
  149. data/site/assets/javascripts/lunr/min/lunr.ar.min.js +1 -0
  150. data/site/assets/javascripts/lunr/min/lunr.da.min.js +18 -0
  151. data/site/assets/javascripts/lunr/min/lunr.de.min.js +18 -0
  152. data/site/assets/javascripts/lunr/min/lunr.du.min.js +18 -0
  153. data/site/assets/javascripts/lunr/min/lunr.el.min.js +1 -0
  154. data/site/assets/javascripts/lunr/min/lunr.es.min.js +18 -0
  155. data/site/assets/javascripts/lunr/min/lunr.fi.min.js +18 -0
  156. data/site/assets/javascripts/lunr/min/lunr.fr.min.js +18 -0
  157. data/site/assets/javascripts/lunr/min/lunr.he.min.js +1 -0
  158. data/site/assets/javascripts/lunr/min/lunr.hi.min.js +1 -0
  159. data/site/assets/javascripts/lunr/min/lunr.hu.min.js +18 -0
  160. data/site/assets/javascripts/lunr/min/lunr.hy.min.js +1 -0
  161. data/site/assets/javascripts/lunr/min/lunr.it.min.js +18 -0
  162. data/site/assets/javascripts/lunr/min/lunr.ja.min.js +1 -0
  163. data/site/assets/javascripts/lunr/min/lunr.jp.min.js +1 -0
  164. data/site/assets/javascripts/lunr/min/lunr.kn.min.js +1 -0
  165. data/site/assets/javascripts/lunr/min/lunr.ko.min.js +1 -0
  166. data/site/assets/javascripts/lunr/min/lunr.multi.min.js +1 -0
  167. data/site/assets/javascripts/lunr/min/lunr.nl.min.js +18 -0
  168. data/site/assets/javascripts/lunr/min/lunr.no.min.js +18 -0
  169. data/site/assets/javascripts/lunr/min/lunr.pt.min.js +18 -0
  170. data/site/assets/javascripts/lunr/min/lunr.ro.min.js +18 -0
  171. data/site/assets/javascripts/lunr/min/lunr.ru.min.js +18 -0
  172. data/site/assets/javascripts/lunr/min/lunr.sa.min.js +1 -0
  173. data/site/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +1 -0
  174. data/site/assets/javascripts/lunr/min/lunr.sv.min.js +18 -0
  175. data/site/assets/javascripts/lunr/min/lunr.ta.min.js +1 -0
  176. data/site/assets/javascripts/lunr/min/lunr.te.min.js +1 -0
  177. data/site/assets/javascripts/lunr/min/lunr.th.min.js +1 -0
  178. data/site/assets/javascripts/lunr/min/lunr.tr.min.js +18 -0
  179. data/site/assets/javascripts/lunr/min/lunr.vi.min.js +1 -0
  180. data/site/assets/javascripts/lunr/min/lunr.zh.min.js +1 -0
  181. data/site/assets/javascripts/lunr/tinyseg.js +206 -0
  182. data/site/assets/javascripts/lunr/wordcut.js +6708 -0
  183. data/site/assets/javascripts/workers/search.2c215733.min.js +42 -0
  184. data/site/assets/javascripts/workers/search.2c215733.min.js.map +7 -0
  185. data/site/assets/stylesheets/main.484c7ddc.min.css +1 -0
  186. data/site/assets/stylesheets/main.484c7ddc.min.css.map +1 -0
  187. data/site/assets/stylesheets/palette.ab4e12ef.min.css +1 -0
  188. data/site/assets/stylesheets/palette.ab4e12ef.min.css.map +1 -0
  189. data/site/concepts/index.html +3455 -0
  190. data/site/examples/basic-chat/index.html +2880 -0
  191. data/site/examples/index.html +2907 -0
  192. data/site/examples/mcp-server/index.html +3018 -0
  193. data/site/examples/multi-robot-network/index.html +3131 -0
  194. data/site/examples/rails-application/index.html +3329 -0
  195. data/site/examples/tool-usage/index.html +3085 -0
  196. data/site/getting-started/configuration/index.html +3745 -0
  197. data/site/getting-started/index.html +2572 -0
  198. data/site/getting-started/installation/index.html +2981 -0
  199. data/site/getting-started/quick-start/index.html +2942 -0
  200. data/site/guides/building-robots/index.html +4290 -0
  201. data/site/guides/creating-networks/index.html +3858 -0
  202. data/site/guides/index.html +2586 -0
  203. data/site/guides/mcp-integration/index.html +3581 -0
  204. data/site/guides/memory/index.html +3586 -0
  205. data/site/guides/rails-integration/index.html +4019 -0
  206. data/site/guides/streaming/index.html +3157 -0
  207. data/site/guides/using-tools/index.html +3802 -0
  208. data/site/index.html +2671 -0
  209. data/site/search/search_index.json +1 -0
  210. data/site/sitemap.xml +183 -0
  211. data/site/sitemap.xml.gz +0 -0
  212. data/site/tags.json +1 -0
  213. data/temp.md +6 -0
  214. data/tool_manifest_plan.md +155 -0
  215. metadata +154 -92
  216. data/docs/examples/rails-application.md +0 -419
  217. data/docs/guides/ractor-parallelism.md +0 -364
  218. data/docs/guides/rails-integration.md +0 -681
  219. data/docs/superpowers/plans/2026-04-14-ractor-integration.md +0 -1538
  220. data/docs/superpowers/specs/2026-04-14-ractor-integration-design.md +0 -258
  221. data/lib/generators/robot_lab/install_generator.rb +0 -90
  222. data/lib/generators/robot_lab/job_generator.rb +0 -40
  223. data/lib/generators/robot_lab/robot_generator.rb +0 -55
  224. data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -42
  225. data/lib/generators/robot_lab/templates/job.rb.tt +0 -21
  226. data/lib/generators/robot_lab/templates/migration.rb.tt +0 -32
  227. data/lib/generators/robot_lab/templates/result_model.rb.tt +0 -52
  228. data/lib/generators/robot_lab/templates/robot.rb.tt +0 -31
  229. data/lib/generators/robot_lab/templates/robot_job.rb.tt +0 -18
  230. data/lib/generators/robot_lab/templates/robot_test.rb.tt +0 -34
  231. data/lib/generators/robot_lab/templates/routing_robot.rb.tt +0 -59
  232. data/lib/generators/robot_lab/templates/thread_model.rb.tt +0 -40
  233. data/lib/robot_lab/document_store.rb +0 -155
  234. data/lib/robot_lab/ractor_boundary.rb +0 -42
  235. data/lib/robot_lab/ractor_job.rb +0 -37
  236. data/lib/robot_lab/ractor_memory_proxy.rb +0 -85
  237. data/lib/robot_lab/ractor_network_scheduler.rb +0 -154
  238. data/lib/robot_lab/ractor_worker_pool.rb +0 -117
  239. data/lib/robot_lab/rails_integration/engine.rb +0 -29
  240. data/lib/robot_lab/rails_integration/job.rb +0 -158
  241. data/lib/robot_lab/rails_integration/railtie.rb +0 -51
  242. data/lib/robot_lab/rails_integration/turbo_stream_callbacks.rb +0 -72
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a1898a9909e7fdd795350b7f10cf80c57d69c1cec1b2533e56b9652cc2b3930
4
- data.tar.gz: 641d4bd4022788a4ce53965a1ff8413ccf1420f71a1981f975618f825c29b80c
3
+ metadata.gz: '020282572c5c4eca7e0c44d60920752df53043df99aa54a2018b68e049404945'
4
+ data.tar.gz: 2f0d0e92ff91a8eb24ff73065e1b91091c57cb6abcf3a0c3349c2370ab877973
5
5
  SHA512:
6
- metadata.gz: d51060ef5a929f5d9b895ba7e11220d47765fb92a342e9c3c76d5c223043747d53e7b924c9ecc53fccc90b90a0b08c180e75d5955527cc8b3cd99411a9c64026
7
- data.tar.gz: c59f404518a69d97c65d960982367c582b8410d3754d3cf238ab8117f400eb229a02891bb449ab311bceaa16f0382c6cfd355c8f976bcc8f49b8191f8035e221
6
+ metadata.gz: 7d99549cbb526071e48e2d66e9771553491404ec437f21465190517fc4451418a48024cd5e1fc8482ae96ea061492fb632f8f264048d8941e20090faa1213d22
7
+ data.tar.gz: 0fe87b21e72c03a65e3809dfab01d3d6735919101ab8f2f8d9cd9d64a52394c06fc12f9fc9b648cb9350568c56ac8da111d8a6db9ba841738cbb72ce682708d6
@@ -0,0 +1,32 @@
1
+ ### Local Agent Context: .architecture
2
+
3
+ # Setup & Commands — Exact commands + required env vars.
4
+
5
+ - Configure project: Verify `project_name` and `version` in `.architecture/config.yml` are correct for current setup.
6
+ - Quarterly review schedule is enforced automatically; ensure `review_schedule` is set to `quarterly` in `.architecture/config.yml`.
7
+
8
+ # Code Style & Patterns — Must-follow conventions, backticked.
9
+
10
+ - Ensure any new architectural documentation follows the naming pattern in `.architecture/reviews`.
11
+ - For member roles, adhere to the structured format in `.architecture/members.yml` with fields like `id`, `name`, `title`, and `specialties`.
12
+ - Document architectural reviews extensively, mirroring the detailed style found in `.architecture/reviews/feature-free-will.md`.
13
+
14
+ # Implementation Details — Entry files + compressed playbooks (job/env/rollout).
15
+
16
+ ## Architectural Review Process
17
+
18
+ 1. **Conduct Review**:
19
+ - Read current state and previous findings in `.architecture/reviews/overall-codebase.md`.
20
+ - Compare changes and new resolutions against previous entries like `.architecture/reviews/feature-free-will.md`.
21
+
22
+ 2. **Document Review**:
23
+ - Record new findings and updates in a new markdown file within `.architecture/reviews/`.
24
+ - Follow the format example in existing review files for consistency and effectiveness.
25
+
26
+ 3. **Remove Dead Code**:
27
+ - Audit `network:` parameter usage in relevant function calls.
28
+ - Remove unused parameters and adjust corresponding method calls as documented in reviews.
29
+
30
+ _Warning_: Removing architectural elements based on outdated assumptions can be destructive.
31
+
32
+ By following these structured guidelines and file-specific practices, maintain a coherent and robust architectural documentation process inside the `.architecture` directory.
@@ -0,0 +1,8 @@
1
+ project_name: RobotLab
2
+ version: 0.0.5
3
+ review_schedule: quarterly
4
+ pragmatic_mode:
5
+ enabled: true
6
+ applies_to:
7
+ - reviews
8
+ - adrs
@@ -0,0 +1,60 @@
1
+ members:
2
+ - id: systems_architect
3
+ name: Systems Architect
4
+ title: Principal Systems Architect
5
+ specialties:
6
+ - module decomposition
7
+ - dependency management
8
+ - API surface design
9
+ - Zeitwerk autoloading
10
+ perspective: Evaluates overall structure, module boundaries, and dependency flow
11
+
12
+ - id: concurrency_specialist
13
+ name: Concurrency Specialist
14
+ title: Async & Concurrency Engineer
15
+ specialties:
16
+ - async/await patterns
17
+ - fiber-based concurrency
18
+ - race condition prevention
19
+ - message bus architectures
20
+ perspective: Analyzes async patterns, race conditions, and message ordering guarantees
21
+
22
+ - id: api_design_lead
23
+ name: API Design Lead
24
+ title: Developer Experience Architect
25
+ specialties:
26
+ - public API ergonomics
27
+ - configuration hierarchies
28
+ - builder patterns
29
+ - Ruby idioms
30
+ perspective: Evaluates public API surface, developer experience, and Ruby idiomaticness
31
+
32
+ - id: reliability_engineer
33
+ name: Reliability Engineer
34
+ title: Error Handling & Resilience Specialist
35
+ specialties:
36
+ - error hierarchies
37
+ - retry/backoff strategies
38
+ - graceful degradation
39
+ - state machine correctness
40
+ perspective: Assesses error handling, failure modes, and system resilience
41
+
42
+ - id: testing_strategist
43
+ name: Testing Strategist
44
+ title: Quality Assurance Architect
45
+ specialties:
46
+ - test coverage analysis
47
+ - integration vs unit testing
48
+ - mock strategies
49
+ - CI reliability
50
+ perspective: Reviews test architecture, coverage gaps, and testing patterns
51
+
52
+ - id: pragmatic_enforcer
53
+ name: Pragmatic Enforcer
54
+ title: YAGNI & Simplicity Advocate
55
+ specialties:
56
+ - over-engineering detection
57
+ - complexity budgets
58
+ - deferred decisions
59
+ - MVP scoping
60
+ perspective: Challenges unnecessary complexity and advocates for simplest viable solutions
@@ -0,0 +1,490 @@
1
+ # Architecture Review: free_will Branch
2
+
3
+ **Date**: 2026-02-17
4
+ **Review Type**: Feature Branch Review (full codebase on `free_will`)
5
+ **Version**: 0.0.5
6
+ **Previous Review**: `overall-codebase.md` (2026-02-16)
7
+ **Reviewers**: Systems Architect, Concurrency Specialist, API Design Lead, Reliability Engineer, Testing Strategist, Pragmatic Enforcer
8
+
9
+ ## Executive Summary
10
+
11
+ The `free_will` branch represents RobotLab v0.0.5 with significant improvements since the previous review. Three of the four "Critical Actions" from the 2026-02-16 review have been addressed: the bus processing guard is now in core, `dispatch_async` uses Async exclusively (no Thread leak), and Memory nil-value handling is fixed. The addition of `RunConfig` for hierarchical configuration is well-executed and fills a real need.
12
+
13
+ The remaining technical debt centers on dead code (streaming module, ghost `network:` parameter, unused RedisBackend) and documentation drift. The architecture is sound and appropriate for a v0.0.5 framework.
14
+
15
+ **Overall Assessment**: Adequate -- trending toward Strong
16
+
17
+ **Key Findings**:
18
+ - 3 of 4 critical actions from previous review are resolved
19
+ - `RunConfig` is a solid addition that unifies the configuration hierarchy
20
+ - `network:` parameter in `Robot#run` is vestigial dead code -- never populated from the pipeline
21
+ - Streaming module remains orphaned (95 lines, 22 event types, zero consumers)
22
+ - Test coverage is strong (27 files, 1,049+ assertions in robot_test alone) but no integration suite
23
+
24
+ **Critical Actions**:
25
+ - Remove the `network:` parameter from `Robot#run` and the `network&.network&.mcp` chain in MCPManagement
26
+ - Integrate or remove the streaming module before v0.1.0
27
+
28
+ ---
29
+
30
+ ## Delta from Previous Review (2026-02-16)
31
+
32
+ ### Resolved
33
+
34
+ | Previous Finding | Status | How Resolved |
35
+ |---|---|---|
36
+ | Async re-entrancy in Robot#run (High) | **RESOLVED** | `BusMessaging#handle_incoming_delivery` now uses `@bus_processing` flag + `@bus_queue` to serialize deliveries |
37
+ | dispatch_async Thread leak (Medium) | **RESOLVED** | `Utils#dispatch_async` simplified to `Async { block.call }` -- no Thread.new fallback |
38
+ | Memory nil-value handling (Medium) | **RESOLVED** | `get_single` now uses `@backend.key?(key)` instead of nil check |
39
+ | No RunConfig for shared configuration | **RESOLVED** | `RunConfig` class added with field categories, merge semantics, and `apply_to(chat)` |
40
+
41
+ ### Remaining
42
+
43
+ | Previous Finding | Status | Notes |
44
+ |---|---|---|
45
+ | Ghost NetworkRun references (Medium) | **OPEN** | `network:` param in Robot#run and `network&.network&.mcp` in MCPManagement |
46
+ | Streaming module orphaned (Medium) | **OPEN** | Still not wired into Robot#run or Network#run |
47
+ | Adapter directory mismatch (Low) | **OPEN** | test_helper references adapters SimpleCov group; no adapters/ dir exists |
48
+ | Eager loading at boot (Medium) | **OPEN** | `loader.eager_load` still unconditional |
49
+ | RedisBackend untested/unused (Low) | **OPEN** | 50 lines, no test coverage, auto-falls back to Hash |
50
+ | ToolManifest usage unclear (Low) | **OPEN** | Full collection API but not used in execution path |
51
+ | No integration tests (High) | **OPEN** | Rakefile `integration` task exists but no test/integration/ directory |
52
+ | MCP auto-reconnect (Low) | **OPEN** | `call_tool` still raises MCPError on disconnect with no retry |
53
+
54
+ ### New Findings
55
+
56
+ See individual member reviews below.
57
+
58
+ ---
59
+
60
+ ## System Overview
61
+
62
+ ### File Counts
63
+ | Area | Files | Lines (approx) |
64
+ |------|-------|-------|
65
+ | Core lib (`lib/robot_lab/`) | 36 | ~3,970 |
66
+ | Robot concerns (`lib/robot_lab/robot/`) | 3 | ~370 |
67
+ | MCP (`lib/robot_lab/mcp/`) | 6 | ~600 |
68
+ | Streaming (`lib/robot_lab/streaming/`) | 3 | ~200 |
69
+ | Tests (`test/`) | 27 | ~5,400 |
70
+ | Examples | 15 scripts | N/A |
71
+
72
+ ### Dependency Graph (Core)
73
+
74
+ ```
75
+ RobotLab (module)
76
+ +-- Config (MywayConfig::Base)
77
+ | +-- configures RubyLLM + PromptManager
78
+ +-- RunConfig (standalone)
79
+ | +-- LLM/Tool/Callback/Infra fields
80
+ | +-- merge semantics, apply_to(chat)
81
+ +-- Robot (RubyLLM::Agent)
82
+ | +-- TemplateRendering (module)
83
+ | +-- MCPManagement (module)
84
+ | +-- BusMessaging (module) [processing guard]
85
+ +-- Network
86
+ | +-- SimpleFlow::Pipeline
87
+ | +-- Task (step wrapper, per-task RunConfig)
88
+ | +-- Memory (shared)
89
+ +-- Memory
90
+ | +-- Waiter (ConditionVariable)
91
+ | +-- StateProxy (method_missing)
92
+ | +-- MemoryChange (notification)
93
+ | +-- RedisBackend (optional, unused)
94
+ +-- MCP::Client
95
+ | +-- MCP::Server (config)
96
+ | +-- Transports (Stdio, WebSocket, SSE, StreamableHTTP)
97
+ +-- Tool (RubyLLM::Tool)
98
+ | +-- AskUser (built-in)
99
+ | +-- ToolManifest (registry, possibly unused)
100
+ +-- Message hierarchy
101
+ | +-- TextMessage, ToolCallMessage, ToolResultMessage
102
+ | +-- ToolMessage (internal)
103
+ | +-- UserMessage
104
+ +-- RobotMessage (Data.define, bus envelope)
105
+ +-- RobotResult (execution result)
106
+ +-- Streaming::Events (orphaned)
107
+ +-- Streaming::Context (orphaned)
108
+ +-- Utils, Error, Errors, ToolConfig
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Individual Member Reviews
114
+
115
+ ### Systems Architect - Principal Systems Architect
116
+
117
+ **Perspective**: Evaluates overall structure, module boundaries, and dependency flow
118
+
119
+ #### Key Observations
120
+ - RunConfig is a well-designed addition that cleanly addresses configuration hierarchy without over-engineering
121
+ - The Robot concern extraction (TemplateRendering, MCPManagement, BusMessaging) continues to be clean
122
+ - `robot_lab.rb` entry point is well-structured with factory methods
123
+
124
+ #### Strengths
125
+ 1. **RunConfig merge semantics**: `more-specific wins` is intuitive; `from_front_matter` bridges template config elegantly
126
+ 2. **Configuration chain is complete**: Global -> Network -> Task -> Robot -> Template -> Runtime, all via RunConfig
127
+ 3. **BusMessaging processing guard**: The `@bus_processing` + `@bus_queue` pattern is simple and correct
128
+ 4. **Factory pattern stability**: `RobotLab.build()` and `create_network()` haven't changed across versions -- good API stability
129
+
130
+ #### Concerns
131
+ 1. **Dead `network:` parameter in Robot#run** (Impact: Medium)
132
+ - Issue: `Robot#run` accepts `network:` but it's never populated. `Network#run` passes `network_memory:` and `network_config:` via run_params, but not `network:`. In `MCPManagement#resolve_mcp_hierarchy`, the chain `network&.network&.mcp` calls `.network` on whatever `network:` is -- but since it's always nil, this is dead code.
133
+ - Evidence: `Task#call` builds `run_params` with `:network_memory` and `:network_config` keys. `Robot#extract_run_context` does NOT extract a `:network` key. So `network:` in `Robot#run` always receives nil.
134
+ - Recommendation: Remove the `network:` parameter from `Robot#run`. Replace `network&.network&.mcp` with just `network_config&.mcp` in MCPManagement. This is the residue of the removed `NetworkRun` class.
135
+
136
+ 2. **Eager loading remains unconditional** (Impact: Medium)
137
+ - Issue: `loader.eager_load` at line 69 of `robot_lab.rb` forces all classes to load at require time, including streaming, MCP transports, and Redis backend regardless of whether they're needed.
138
+ - Recommendation: Gate behind `if defined?(Rails) || ENV['ROBOT_LAB_EAGER_LOAD']`
139
+
140
+ 3. **Dual error files: `error.rb` + `errors.rb`** (Impact: Low)
141
+ - Issue: `error.rb` defines the exception hierarchy (`Error`, `ConfigurationError`, etc.) while `errors.rb` defines the `Errors` utility module (`serialize`, `deserialize`, `capture`). The names are confusingly similar.
142
+ - Recommendation: Rename `errors.rb` to something more descriptive like `error_serializer.rb` or merge into `error.rb`.
143
+
144
+ #### Pragmatic Analysis
145
+ | Item | Necessity | Complexity | Ratio | Recommendation |
146
+ |------|-----------|-----------|-------|---------------|
147
+ | Remove `network:` dead code | 8 | 1 | 0.1 | **Do now** |
148
+ | Conditional eager_load | 5 | 1 | 0.2 | **Do now** |
149
+ | Rename errors.rb | 3 | 1 | 0.3 | **Defer** |
150
+
151
+ #### Recommendations
152
+ 1. **Remove `network:` parameter and ghost chain** (Priority: High, Effort: Small)
153
+ 2. **Make eager_load conditional** (Priority: Medium, Effort: Small)
154
+
155
+ ---
156
+
157
+ ### Concurrency Specialist - Async & Concurrency Engineer
158
+
159
+ **Perspective**: Analyzes async patterns, race conditions, and message ordering guarantees
160
+
161
+ #### Key Observations
162
+ - The processing guard in BusMessaging is correctly implemented and addresses the critical re-entrancy bug
163
+ - `dispatch_async` is now Async-only, eliminating the Thread leak concern
164
+ - Memory's reactive infrastructure uses proper mutex discipline
165
+
166
+ #### Strengths
167
+ 1. **Processing guard is correct**: `@bus_processing` flag set in `process_delivery` with `ensure` block for cleanup. Queue drained sequentially via `drain_bus_queue`. Error handling nacks the delivery and re-raises wrapped in BusError.
168
+ 2. **dispatch_async is clean**: `Async { block.call }` -- simple, no Thread.new, no double-wrapping. Relies on Async's own task management.
169
+ 3. **Waiter is thread-safe**: Uses Mutex + ConditionVariable with `@signaled` flag to prevent missed wakeups. Timeout calculation is correct.
170
+ 4. **Memory nil-value fix is correct**: `@backend.key?(key)` distinguishes "not set" from "set to nil".
171
+
172
+ #### Concerns
173
+ 1. **Async exception swallowing** (Impact: Medium)
174
+ - Issue: `dispatch_async` uses `Async { block.call }`. Exceptions inside Async tasks are captured by the Async framework but not propagated to callers. Memory subscription callbacks that raise exceptions will be silently swallowed unless there's an active Async reactor with error handling.
175
+ - Recommendation: Wrap the callback in a rescue block that logs or delegates to a configurable error handler:
176
+ ```ruby
177
+ def dispatch_async(&block)
178
+ Async do
179
+ block.call
180
+ rescue => e
181
+ RobotLab.config.logger&.error("Async dispatch error: #{e.message}")
182
+ end
183
+ end
184
+ ```
185
+
186
+ 2. **BusMessaging drain_bus_queue is non-reentrant but has edge case** (Impact: Low)
187
+ - Issue: `drain_bus_queue` processes deliveries via `process_delivery`, which sets `@bus_processing = true` then `false` in ensure. If `drain_bus_queue` calls `process_delivery` and the handler enqueues more messages to `@bus_queue` (via a send_message that results in a delivery to self), these will be picked up by the same `drain_bus_queue` loop. This is correct behavior but could lead to unbounded queue growth if a handler always self-messages.
188
+ - Recommendation: Document that self-messaging in handlers requires a termination condition. Consider a max drain depth.
189
+
190
+ 3. **Memory subscription callbacks can deadlock via re-entry** (Impact: Low)
191
+ - Issue: If a subscription callback calls `memory.set(key, value)`, it triggers `notify_subscribers_async` which acquires `@subscription_mutex`. Since `dispatch_async` runs in a separate Async task, this should be safe. However, if the callback is synchronous (e.g., inside a test without Async), it could deadlock.
192
+ - Recommendation: This is safe in practice because `dispatch_async` always wraps in Async. Document that Memory's reactive features require an Async reactor.
193
+
194
+ #### Recommendations
195
+ 1. **Add error logging to dispatch_async** (Priority: Medium, Effort: Small)
196
+ 2. **Document self-messaging guard requirement** (Priority: Low, Effort: Small)
197
+
198
+ ---
199
+
200
+ ### API Design Lead - Developer Experience Architect
201
+
202
+ **Perspective**: Evaluates public API surface, developer experience, and Ruby idiomaticness
203
+
204
+ #### Key Observations
205
+ - RunConfig's dual construction patterns (keyword + block DSL) are elegant and Ruby-idiomatic
206
+ - The `with_*` chaining on Robot remains clean
207
+ - `reply` alias on RobotResult improves ergonomics
208
+
209
+ #### Strengths
210
+ 1. **RunConfig construction is flexible**: `RunConfig.new(model: "x")` for simple cases, `RunConfig.new { |c| c.model("x") }` for DSL, `config.merge(other)` for composition
211
+ 2. **Progressive disclosure maintained**: `RobotLab.build.run("Hello")` still works with zero configuration
212
+ 3. **on_message arity detection**: 1-arg = auto-ack, 2-arg = manual -- clever, well-documented in BusMessaging comments
213
+ 4. **Consistent serialization**: Every domain object has `to_h`, `to_json`, and most have `from_hash`
214
+
215
+ #### Concerns
216
+ 1. **Robot#initialize still takes 20+ parameters** (Impact: Medium)
217
+ - Issue: Despite RunConfig, the constructor still accepts `model:`, `temperature:`, `mcp:`, `tools:`, etc. as direct kwargs alongside `config:`. The constructor logic (lines 134-148) merges these into a RunConfig internally. This creates two valid construction patterns that produce the same result.
218
+ - Recommendation: For v0.1.0, consider deprecating individual LLM kwargs in favor of `config:` only. This would simplify the constructor to ~8 parameters (name, template, system_prompt, context, description, local_tools, config, bus).
219
+
220
+ 2. **Robot#run kwargs serve dual purpose** (Impact: Medium)
221
+ - Issue: `**kwargs` in `Robot#run` are split between template re-rendering (`kwargs.except(:with)`) and ask options (`kwargs.slice(:with)`). This coupling means any new template parameter name could collide with future ask() options.
222
+ - Recommendation: Use explicit named parameter: `run(message, context: {}, with: [])`. This makes the split visible in the API.
223
+
224
+ 3. **`config:` name collision in Network#task** (Impact: Low)
225
+ - Issue: `Network#task` accepts `config:` for per-task RunConfig. But `config` is also a common context hash key. If a user passes `task :billing, bot, config: some_run_config, context: { config: "billing" }`, the intent is clear but the parameter name overlap is confusing.
226
+ - Recommendation: Acceptable for now. The types are distinct (RunConfig vs Hash value).
227
+
228
+ 4. **spawn returns bare Robot without on_message** (Impact: Low)
229
+ - Issue: `Robot#spawn` creates a new robot on the shared bus, but the spawned robot has no `on_message` handler by default. Messages sent to it will trigger `handle_message_via_llm` (default handler), which calls `run()` and replies. This is fine for simple cases but could be surprising.
230
+ - Recommendation: Document that spawned robots default to LLM-pass-through messaging unless `on_message` is set.
231
+
232
+ #### Pragmatic Analysis
233
+ | Item | Necessity | Complexity | Ratio | Recommendation |
234
+ |------|-----------|-----------|-------|---------------|
235
+ | Deprecate individual LLM kwargs | 5 | 3 | 0.6 | **Defer to v0.1.0** |
236
+ | Explicit context: in run() | 6 | 2 | 0.3 | **Do short-term** |
237
+ | Document spawn behavior | 4 | 1 | 0.3 | **Do now** |
238
+
239
+ #### Recommendations
240
+ 1. **Separate template context from ask options in Robot#run** (Priority: Medium, Effort: Small)
241
+ 2. **Document spawn default messaging behavior** (Priority: Low, Effort: Small)
242
+
243
+ ---
244
+
245
+ ### Reliability Engineer - Error Handling & Resilience Specialist
246
+
247
+ **Perspective**: Assesses error handling, failure modes, and system resilience
248
+
249
+ #### Key Observations
250
+ - Error hierarchy unchanged and appropriate (6 error classes)
251
+ - MCP connection failures continue to degrade gracefully
252
+ - The `Errors.capture` utility provides clean error envelopes
253
+
254
+ #### Strengths
255
+ 1. **BusMessaging error handling is correct**: `process_delivery` rescues all exceptions, nacks the delivery if pending, and re-raises as BusError with context
256
+ 2. **RunConfig validates field names**: `set()` raises ArgumentError for unknown fields, preventing silent typos
257
+ 3. **Memory#delete protects reserved keys**: Raises ArgumentError when attempting to delete `:data`, `:results`, etc.
258
+ 4. **Template rendering defers gracefully**: Missing required parameters don't crash -- they defer rendering until `run()` when context is available
259
+
260
+ #### Concerns
261
+ 1. **Async exceptions still silently swallowed** (Impact: Medium)
262
+ - Issue: As noted by Concurrency Specialist -- `dispatch_async` wraps in Async but doesn't catch/log errors. This affects Memory subscription callbacks and Network broadcast handlers.
263
+ - Recommendation: Add `rescue => e` with configurable error handler. Default to `RobotLab.config.logger.error`.
264
+
265
+ 2. **MCP Client reconnection still absent** (Impact: Medium)
266
+ - Issue: `MCP::Client#call_tool` raises `MCPError` if not connected. No auto-reconnect. Long-running robots using MCP tools will fail permanently if the MCP server restarts.
267
+ - Recommendation: Add a `reconnect` option to `call_tool`: try once, on MCPError attempt `connect` then retry. Single retry, no exponential backoff needed for v0.0.x.
268
+
269
+ 3. **Config.mcp / Config.tools may not exist** (Impact: Low)
270
+ - Issue: `MCPManagement#resolve_mcp_hierarchy` falls back to `RobotLab.config.mcp`. If the MywayConfig defaults.yml doesn't define `mcp:`, this could raise NoMethodError. Same for `tools`.
271
+ - Evidence: Would need to check `lib/robot_lab/config/defaults.yml` to verify.
272
+ - Recommendation: Use `RobotLab.config.respond_to?(:mcp) ? RobotLab.config.mcp : nil` or add defaults.
273
+
274
+ 4. **Memory#clone doesn't deep-copy complex values** (Impact: Low)
275
+ - Issue: Per the CHANGELOG, `clone` now "results and messages are referenced directly instead of duplicated." This means cloned memory shares mutable objects with the original. If a robot modifies a result's debug fields (`prompt`, `history`, `raw`), the original memory is affected.
276
+ - Recommendation: Acceptable tradeoff for performance. Document that clone shares result/message references.
277
+
278
+ #### Recommendations
279
+ 1. **Add configurable async error handler** (Priority: Medium, Effort: Small)
280
+ 2. **Add single-retry MCP reconnection** (Priority: Low, Effort: Small)
281
+ 3. **Verify Config defaults for mcp/tools** (Priority: Medium, Effort: Small)
282
+
283
+ ---
284
+
285
+ ### Testing Strategist - Quality Assurance Architect
286
+
287
+ **Perspective**: Reviews test architecture, coverage gaps, and testing patterns
288
+
289
+ #### Key Observations
290
+ - Test suite is comprehensive: 27 files, 1,049+ assertions in robot_test.rb alone
291
+ - RunConfig has a dedicated 39-test/380-assertion suite
292
+ - Memory tests cover reactive features including concurrent access
293
+ - Bus messaging tests verify the processing guard
294
+
295
+ #### Strengths
296
+ 1. **RunConfig tests are excellent**: 39 tests covering construction, merge, apply_to, front_matter, serialization
297
+ 2. **Memory reactive tests**: Concurrent read/write with 10 threads x 100 ops, subscription notification, blocking wait
298
+ 3. **Robot bus tests**: Processing guard verification, queue draining, error-during-drain handling
299
+ 4. **Test helpers are well-designed**: `build_robot`, `build_network`, `build_config`, `wait_until` with customizable timeout
300
+
301
+ #### Concerns
302
+ 1. **No integration test directory** (Impact: High)
303
+ - Issue: `Rakefile` defines an `integration` task pointing to `test/integration/**/*_test.rb` but the directory doesn't exist. End-to-end workflows (Robot -> Network -> Memory -> Bus) are only tested in examples, not in the test suite.
304
+ - Recommendation: Create `test/integration/` with:
305
+ - `network_pipeline_test.rb`: Task -> Robot -> Memory flow
306
+ - `bus_round_trip_test.rb`: send_message -> on_message -> send_reply
307
+ - `mcp_tool_discovery_test.rb`: Client -> list_tools -> call_tool (with MockTransport)
308
+
309
+ 2. **Streaming module tests are isolated** (Impact: Medium)
310
+ - Issue: `streaming_test.rb` tests Event constants and Context in isolation. Since streaming is not wired into execution, these tests only verify the data structures exist, not that they work.
311
+ - Recommendation: Either remove streaming tests (they'll be recreated when streaming is integrated) or clearly mark them as "infrastructure only."
312
+
313
+ 3. **Network#run not tested end-to-end** (Impact: Medium)
314
+ - Issue: `network_test.rb` tests initialization, task management, visualization, and serialization. But there's no test that calls `network.run()` and verifies the result flows through the pipeline. The pipeline execution is delegated to SimpleFlow which is tested externally, but the RobotLab-specific wiring (memory injection, config passing) is untested.
315
+ - Recommendation: Add a test that creates a 2-robot network, runs it, and verifies both robots received shared memory and the final result contains both robots' output.
316
+
317
+ 4. **MCP transport tests need real-world validation** (Impact: Low)
318
+ - Issue: MCP tests use MockTransport. While this verifies the client API, it doesn't test actual transport behavior (stdio process spawning, WebSocket handshake, SSE reconnection).
319
+ - Recommendation: Add a lightweight integration test with a simple stdio MCP server (e.g., a Ruby script that responds to `tools/list`). Low effort, high value.
320
+
321
+ #### Pragmatic Analysis
322
+ | Item | Necessity | Complexity | Ratio | Recommendation |
323
+ |------|-----------|-----------|-------|---------------|
324
+ | Integration test suite | 8 | 4 | 0.5 | **Do short-term** |
325
+ | Network#run end-to-end test | 7 | 2 | 0.3 | **Do now** |
326
+ | MCP stdio integration test | 5 | 3 | 0.6 | **Do short-term** |
327
+ | Clean up streaming tests | 3 | 1 | 0.3 | **Defer** |
328
+
329
+ #### Recommendations
330
+ 1. **Create integration test directory with 3 core workflows** (Priority: High, Effort: Medium)
331
+ 2. **Add Network#run pipeline test** (Priority: High, Effort: Small)
332
+
333
+ ---
334
+
335
+ ### Pragmatic Enforcer - YAGNI & Simplicity Advocate
336
+
337
+ **Perspective**: Challenges unnecessary complexity and advocates for simplest viable solutions
338
+
339
+ #### Key Observations
340
+ - RunConfig is a justified addition -- it solves a real configuration hierarchy problem with appropriate complexity
341
+ - The processing guard in BusMessaging is simple and correct -- not over-engineered
342
+ - Streaming module remains the largest piece of speculative infrastructure
343
+
344
+ #### Pragmatic Scorecard
345
+
346
+ | Feature | Necessity (0-10) | Complexity (0-10) | Ratio | Recommendation |
347
+ |---------|-----------------|-------------------|-------|----------------|
348
+ | Robot core + with_* chaining | 10 | 4 | 0.4 | **Keep** |
349
+ | Network/Pipeline | 9 | 5 | 0.6 | **Keep** |
350
+ | RunConfig | 8 | 3 | 0.4 | **Keep** -- justified, well-sized |
351
+ | Memory (reactive) | 8 | 6 | 0.8 | **Keep** |
352
+ | Bus messaging + guard | 7 | 4 | 0.6 | **Keep** |
353
+ | MCP integration | 7 | 6 | 0.9 | **Keep** |
354
+ | Tool hierarchy (ToolConfig) | 6 | 3 | 0.5 | **Keep** |
355
+ | Streaming events | 4 | 4 | 1.0 | **Remove** -- still orphaned |
356
+ | Redis backend | 3 | 3 | 1.0 | **Remove** -- still unused |
357
+ | ToolManifest | 3 | 2 | 0.7 | **Audit** -- still unclear |
358
+ | `network:` dead parameter | 0 | 1 | inf | **Remove** -- pure dead code |
359
+
360
+ #### Concerns
361
+ 1. **Streaming infrastructure: still 95 lines with zero consumers** (Pragmatic Score: 1.0)
362
+ - Issue: Same as previous review. `Streaming::Events` (95 lines, 22 event types), `Streaming::Context` (145 lines), and `Streaming::SequenceCounter` -- none connected to Robot#run or Network#run. Cost of recreating when needed: near zero.
363
+ - Recommendation: Move to a feature branch. Remove from main/free_will.
364
+
365
+ 2. **RedisBackend: still 50 lines with no tests** (Pragmatic Score: 1.0)
366
+ - Issue: `RedisBackend` (lines 807-857 of memory.rb) implements a full key-value interface on Redis. No tests exercise it. The auto-detection path silently falls back to Hash. No examples use it.
367
+ - Recommendation: Extract to a separate file and gate behind `require 'robot_lab/memory/redis_backend'`. Don't load by default.
368
+
369
+ 3. **ToolManifest: 217 lines, used nowhere in execution** (Pragmatic Score: 0.7)
370
+ - Issue: `ToolManifest` provides Enumerable, merge, replace, fetch, from_hash -- a full collection API. Robot uses `@local_tools + @mcp_tools` arrays directly. `ToolConfig.filter_tools` operates on arrays. ToolManifest appears to be a public API surface that nothing internal consumes.
371
+ - Recommendation: Keep if intended as a user-facing registry API. Remove if not. Audit with `grep -r ToolManifest` to verify.
372
+
373
+ 4. **RunConfig is well-sized** (Pragmatic Score: 0.4)
374
+ - RunConfig is 184 lines with clear field categories, merge semantics, and serialization. It solves a real problem (configuration hierarchy) without over-engineering. Good pragmatic balance.
375
+
376
+ #### Recommendations
377
+ 1. **Remove streaming module** (Priority: Medium, Effort: Small)
378
+ 2. **Extract RedisBackend to optional require** (Priority: Low, Effort: Small)
379
+ 3. **Audit ToolManifest usage** (Priority: Low, Effort: Small)
380
+ 4. **Remove dead `network:` parameter** (Priority: High, Effort: Small)
381
+
382
+ ---
383
+
384
+ ## Collaborative Discussion
385
+
386
+ ### Consensus Points
387
+
388
+ All reviewers agree on:
389
+ 1. **Core architecture is sound and improving**: RunConfig was a well-judged addition; bus processing guard resolves the highest-risk issue from the previous review
390
+ 2. **`network:` parameter is dead code**: Must be removed -- it creates confusion and references a non-existent class
391
+ 3. **Streaming module should be removed or integrated**: Two consecutive reviews flagging it as orphaned is sufficient signal
392
+ 4. **Integration tests are overdue**: The framework is complex enough that unit tests alone can't verify the wiring between components
393
+
394
+ ### Points of Discussion
395
+
396
+ - **Systems Architect** and **Pragmatic Enforcer** agree on removing the `network:` parameter. **Reliability Engineer** notes this should be done carefully since it's a breaking API change (callers passing `network:` would get an error). **Consensus**: It's a pre-1.0 gem; break the API now. No known callers pass `network:`.
397
+ - **API Design Lead** suggests splitting Robot#run kwargs into explicit `context:` and `with:`. **Pragmatic Enforcer** asks if any users are actually confused by the current behavior. **Consensus**: Add `context:` as a named parameter; keep `**kwargs` for backward compat until v0.1.0.
398
+ - **Testing Strategist** wants 3 integration tests. **Pragmatic Enforcer** suggests starting with 1 (Network#run pipeline) since that's the most complex untested path. **Consensus**: Start with Network#run, add bus round-trip, defer MCP integration test.
399
+
400
+ ---
401
+
402
+ ## Consolidated Findings
403
+
404
+ ### Strengths
405
+ 1. **Configuration hierarchy is complete**: RunConfig flows cleanly through Global -> Network -> Task -> Robot -> Template -> Runtime
406
+ 2. **Bus messaging is safe**: Processing guard prevents the critical async re-entrancy bug
407
+ 3. **Memory reactive API is well-designed**: set/get/subscribe/wait with proper thread-safety
408
+ 4. **Test coverage is strong**: >1:1 test-to-source ratio with per-class coverage
409
+ 5. **API ergonomics**: Progressive disclosure from `build.run("Hello")` to full Network+Bus orchestration
410
+
411
+ ### Areas for Improvement
412
+ 1. **Dead code cleanup**: `network:` parameter, streaming module, RedisBackend, adapter references
413
+ 2. **Integration testing**: No end-to-end test for the Robot-Network-Memory pipeline
414
+ 3. **Error observability**: Async dispatch errors are silently swallowed
415
+ 4. **Documentation accuracy**: CLAUDE.md still references `NetworkRun` in places
416
+
417
+ ### Technical Debt
418
+
419
+ **High Priority**:
420
+ - `network:` dead parameter in Robot#run: Creates confusion and dead code chains. Resolution: Remove parameter and ghost references in MCPManagement. Effort: Small.
421
+
422
+ **Medium Priority**:
423
+ - Streaming module orphaned: 95+ lines of infrastructure with zero consumers. Resolution: Remove or move to branch. Effort: Small.
424
+ - No integration tests: Complex multi-component wiring is untested. Resolution: Add Network#run pipeline test. Effort: Small-Medium.
425
+ - Async error swallowing: Subscription/broadcast callbacks fail silently. Resolution: Add rescue + log in dispatch_async. Effort: Small.
426
+
427
+ **Low Priority**:
428
+ - RedisBackend untested/unused: 50 lines loaded by default. Resolution: Gate behind optional require. Effort: Small.
429
+ - ToolManifest possibly unused: 217 lines with full collection API. Resolution: Audit usage. Effort: Small.
430
+ - Eager load unconditional: Forces all classes at boot. Resolution: Conditional on Rails. Effort: Small.
431
+
432
+ ### Risks
433
+
434
+ **Technical Risks**:
435
+ - **Async error blindness**: Likelihood: Medium (any subscription callback that raises), Impact: Medium (silent data loss), Mitigation: Error logging in dispatch_async
436
+ - **RubyLLM breaking changes**: Likelihood: Medium (dependency is ~> 1.12, pre-stable), Impact: High (Robot inherits from Agent), Mitigation: Pin more tightly or add adapter layer
437
+ - **MCP server disconnection**: Likelihood: Low-Medium (long-running sessions), Impact: Medium (tool calls fail permanently), Mitigation: Single-retry reconnect
438
+
439
+ ---
440
+
441
+ ## Recommendations
442
+
443
+ ### Immediate (0-2 weeks)
444
+ 1. **Remove `network:` dead parameter**: Remove from Robot#run signature. Replace `network&.network&.mcp` with `network_config&.mcp` in MCPManagement. Update CLAUDE.md.
445
+ - Owner: Core
446
+ - Success Criteria: No references to `NetworkRun` or `network.network` in codebase
447
+ 2. **Add error logging to dispatch_async**: Wrap callback in rescue, log to `RobotLab.config.logger.error`.
448
+ - Success Criteria: Exceptions in subscription callbacks appear in logs
449
+ 3. **Add Network#run pipeline test**: Create test that runs a 2-robot network and verifies shared memory, config passing, and result propagation.
450
+ - Success Criteria: `bundle exec rake test` exercises the full pipeline path
451
+
452
+ ### Short-term (2-8 weeks)
453
+ 1. **Remove streaming module**: Move `Streaming::Events`, `Streaming::Context`, `Streaming::SequenceCounter` to a branch. Remove test file.
454
+ - Success Criteria: No orphaned infrastructure code
455
+ 2. **Create integration test directory**: Add `test/integration/` with:
456
+ - `network_pipeline_test.rb`
457
+ - `bus_round_trip_test.rb`
458
+ - Success Criteria: `rake integration` runs 2+ workflow tests
459
+ 3. **Extract RedisBackend**: Move to `lib/robot_lab/memory/redis_backend.rb` with optional require. Don't eager-load.
460
+ - Success Criteria: `require 'robot_lab'` doesn't load Redis code
461
+ 4. **Make eager_load conditional**: Gate behind `defined?(Rails)` or env var.
462
+ - Success Criteria: Gem loads faster in non-Rails contexts
463
+
464
+ ### Long-term (2-6 months)
465
+ 1. **Integrate streaming into execution**: Wire `Streaming::Context` into `Robot#run` to emit lifecycle and delta events via block callback.
466
+ - Success Criteria: `robot.run("Hello") { |event| ... }` yields streaming events
467
+ 2. **Simplify Robot constructor**: For v0.1.0, move individual LLM kwargs to config-only. Reduce constructor to ~8 parameters.
468
+ - Success Criteria: `Robot.new(name:, config:, template:, ...)` is the primary pattern
469
+ 3. **Add MCP auto-reconnect**: Single retry on MCPError in `call_tool`.
470
+ - Success Criteria: Transient MCP server restarts don't break robot sessions
471
+
472
+ ---
473
+
474
+ ## Success Metrics
475
+ 1. **Dead code lines removed**: Current: ~360 (streaming + RedisBackend + dead params) -> Target: 0 (4 weeks)
476
+ 2. **Integration test count**: Current: 0 -> Target: 3+ (6 weeks)
477
+ 3. **Async error visibility**: Current: silently swallowed -> Target: logged (1 week)
478
+ 4. **Doc accuracy**: Current: CLAUDE.md references NetworkRun -> Target: 100% accurate (1 week)
479
+
480
+ ---
481
+
482
+ ## Follow-up
483
+ **Next Review**: After v0.1.0 release or before major feature addition
484
+ **Tracking**: Address Immediate items before merging free_will to main
485
+
486
+ ## Related Documentation
487
+ - `CLAUDE.md`: Project instructions (needs NetworkRun cleanup)
488
+ - `MEMORY.md`: Documents async re-entrancy fix (now in core -- update to reflect)
489
+ - `CHANGELOG.md`: v0.0.5 changes accurately describe RunConfig and fixes
490
+ - Previous review: `.architecture/reviews/overall-codebase.md` (2026-02-16)