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.
- checksums.yaml +4 -4
- data/.architecture/AGENTS.md +32 -0
- data/.architecture/config.yml +8 -0
- data/.architecture/members.yml +60 -0
- data/.architecture/reviews/feature-free-will.md +490 -0
- data/.architecture/reviews/overall-codebase.md +427 -0
- data/.claude/settings.local.json +57 -0
- data/.codex/config.toml +2 -0
- data/.irbrc +2 -2
- data/.rubocop.yml +172 -0
- data/CHANGELOG.md +72 -0
- data/CLAUDE.md +139 -0
- data/README.md +91 -95
- data/Rakefile +109 -3
- data/agent2agent_review.md +192 -0
- data/agentf_improvements.md +253 -0
- data/agents.md +14 -0
- data/docs/examples/index.md +37 -2
- data/docs/getting-started/configuration.md +20 -7
- data/docs/guides/index.md +16 -16
- data/docs/guides/knowledge.md +7 -1
- data/docs/guides/observability.md +132 -0
- data/docs/index.md +30 -3
- data/docs/superpowers/plans/2026-05-06-agentskills.md +1303 -0
- data/docs/superpowers/specs/2026-05-06-agentskills-design.md +247 -0
- data/examples/.envrc +1 -0
- data/examples/01_simple_robot.rb +5 -9
- data/examples/02_tools.rb +5 -9
- data/examples/03_network.rb +8 -9
- data/examples/04_mcp.rb +21 -29
- data/examples/05_streaming.rb +12 -18
- data/examples/06_prompt_templates.rb +11 -19
- data/examples/07_network_memory.rb +16 -31
- data/examples/08_llm_config.rb +10 -22
- data/examples/09_chaining.rb +16 -27
- data/examples/10_memory.rb +12 -28
- data/examples/11_network_introspection.rb +15 -29
- data/examples/12_message_bus.rb +5 -12
- data/examples/13_spawn.rb +5 -10
- data/examples/14_rusty_circuit/.envrc +1 -0
- data/examples/14_rusty_circuit/comic.rb +2 -0
- data/examples/14_rusty_circuit/heckler.rb +1 -1
- data/examples/14_rusty_circuit/open_mic.rb +1 -3
- data/examples/14_rusty_circuit/scout.rb +2 -0
- data/examples/15_memory_network_and_bus/.envrc +1 -0
- data/examples/15_memory_network_and_bus/editorial_pipeline.rb +6 -3
- data/examples/15_memory_network_and_bus/linux_writer.rb +1 -1
- data/examples/15_memory_network_and_bus/output/combined_article.md +6 -6
- data/examples/15_memory_network_and_bus/output/final_article.md +6 -8
- data/examples/15_memory_network_and_bus/output/linux_draft.md +4 -2
- data/examples/15_memory_network_and_bus/output/mac_draft.md +3 -3
- data/examples/15_memory_network_and_bus/output/memory.json +6 -6
- data/examples/15_memory_network_and_bus/output/revision_1.md +10 -11
- data/examples/15_memory_network_and_bus/output/revision_2.md +6 -8
- data/examples/15_memory_network_and_bus/output/windows_draft.md +3 -3
- data/examples/16_writers_room/.envrc +1 -0
- data/examples/16_writers_room/writers_room.rb +2 -4
- data/examples/17_skills.rb +8 -17
- data/examples/18_rails/Gemfile +1 -0
- data/examples/19_token_tracking.rb +9 -15
- data/examples/20_circuit_breaker.rb +10 -19
- data/examples/21_learning_loop.rb +11 -20
- data/examples/22_context_compression.rb +6 -13
- data/examples/23_convergence.rb +6 -17
- data/examples/24_structured_delegation.rb +11 -15
- data/examples/25_history_search.rb +5 -12
- data/examples/26_document_store.rb +6 -13
- data/examples/27_incident_response/incident_response.rb +4 -5
- data/examples/28_mcp_discovery.rb +8 -11
- data/examples/29_ractor_tools.rb +4 -9
- data/examples/30_ractor_network.rb +10 -19
- data/examples/31_launch_assessment.rb +10 -23
- data/examples/32_newsletter_reader.rb +188 -0
- data/examples/33_stock_generator.rb +80 -0
- data/examples/33_stock_predictor.rb +306 -0
- data/examples/34_agentskills.rb +72 -0
- data/examples/README.md +1 -1
- data/examples/common.rb +76 -0
- data/examples/ruboruby.md +423 -0
- data/examples/temp.md +51 -0
- data/lib/robot_lab/agent_skill.rb +63 -0
- data/lib/robot_lab/agent_skill_catalog.rb +74 -0
- data/lib/robot_lab/ask_user.rb +2 -2
- data/lib/robot_lab/bus_poller.rb +12 -5
- data/lib/robot_lab/config.rb +1 -12
- data/lib/robot_lab/delegation_future.rb +1 -1
- data/lib/robot_lab/doom_loop_detector.rb +98 -0
- data/lib/robot_lab/history_compressor.rb +4 -10
- data/lib/robot_lab/mcp/client.rb +1 -2
- data/lib/robot_lab/mcp/connection_poller.rb +3 -3
- data/lib/robot_lab/mcp/server.rb +1 -1
- data/lib/robot_lab/mcp/server_discovery.rb +0 -2
- data/lib/robot_lab/memory.rb +32 -27
- data/lib/robot_lab/memory_change.rb +2 -2
- data/lib/robot_lab/message.rb +4 -4
- data/lib/robot_lab/network.rb +11 -6
- data/lib/robot_lab/robot/agent_skill_matching.rb +99 -0
- data/lib/robot_lab/robot/bus_messaging.rb +9 -27
- data/lib/robot_lab/robot/history_search.rb +4 -1
- data/lib/robot_lab/robot/mcp_management.rb +5 -11
- data/lib/robot_lab/robot/template_rendering.rb +60 -40
- data/lib/robot_lab/robot.rb +323 -206
- data/lib/robot_lab/robot_result.rb +6 -5
- data/lib/robot_lab/run_config.rb +5 -11
- data/lib/robot_lab/script_tool.rb +76 -0
- data/lib/robot_lab/state_proxy.rb +7 -5
- data/lib/robot_lab/tool.rb +3 -3
- data/lib/robot_lab/tool_config.rb +1 -1
- data/lib/robot_lab/tool_manifest.rb +5 -7
- data/lib/robot_lab/user_message.rb +2 -2
- data/lib/robot_lab/version.rb +1 -1
- data/lib/robot_lab/waiter.rb +1 -1
- data/lib/robot_lab.rb +41 -52
- data/logfile +8 -0
- data/mkdocs.yml +2 -3
- data/robot_concurrency.md +38 -0
- data/simple_acp_review.md +298 -0
- data/site/404.html +2300 -0
- data/site/api/core/index.html +2706 -0
- data/site/api/core/memory/index.html +3793 -0
- data/site/api/core/network/index.html +3500 -0
- data/site/api/core/robot/index.html +4566 -0
- data/site/api/core/state/index.html +3390 -0
- data/site/api/core/tool/index.html +3843 -0
- data/site/api/index.html +2635 -0
- data/site/api/mcp/client/index.html +3435 -0
- data/site/api/mcp/index.html +2783 -0
- data/site/api/mcp/server/index.html +3252 -0
- data/site/api/mcp/transports/index.html +3352 -0
- data/site/api/messages/index.html +2641 -0
- data/site/api/messages/text-message/index.html +3087 -0
- data/site/api/messages/tool-call-message/index.html +3159 -0
- data/site/api/messages/tool-result-message/index.html +3252 -0
- data/site/api/messages/user-message/index.html +3212 -0
- data/site/api/streaming/context/index.html +3282 -0
- data/site/api/streaming/events/index.html +3347 -0
- data/site/api/streaming/index.html +2738 -0
- data/site/architecture/core-concepts/index.html +3757 -0
- data/site/architecture/index.html +2797 -0
- data/site/architecture/message-flow/index.html +3238 -0
- data/site/architecture/network-orchestration/index.html +3433 -0
- data/site/architecture/robot-execution/index.html +3140 -0
- data/site/architecture/state-management/index.html +3498 -0
- data/site/assets/css/custom.css +56 -0
- data/site/assets/images/favicon.png +0 -0
- data/site/assets/images/robot_lab.jpg +0 -0
- data/site/assets/javascripts/bundle.79ae519e.min.js +16 -0
- data/site/assets/javascripts/bundle.79ae519e.min.js.map +7 -0
- data/site/assets/javascripts/lunr/min/lunr.ar.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.da.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.de.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.du.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.el.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.es.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.fi.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.fr.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.he.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.hi.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.hu.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.hy.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.it.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.ja.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.jp.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.kn.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.ko.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.multi.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.nl.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.no.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.pt.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.ro.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.ru.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.sa.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.sv.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.ta.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.te.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.th.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.tr.min.js +18 -0
- data/site/assets/javascripts/lunr/min/lunr.vi.min.js +1 -0
- data/site/assets/javascripts/lunr/min/lunr.zh.min.js +1 -0
- data/site/assets/javascripts/lunr/tinyseg.js +206 -0
- data/site/assets/javascripts/lunr/wordcut.js +6708 -0
- data/site/assets/javascripts/workers/search.2c215733.min.js +42 -0
- data/site/assets/javascripts/workers/search.2c215733.min.js.map +7 -0
- data/site/assets/stylesheets/main.484c7ddc.min.css +1 -0
- data/site/assets/stylesheets/main.484c7ddc.min.css.map +1 -0
- data/site/assets/stylesheets/palette.ab4e12ef.min.css +1 -0
- data/site/assets/stylesheets/palette.ab4e12ef.min.css.map +1 -0
- data/site/concepts/index.html +3455 -0
- data/site/examples/basic-chat/index.html +2880 -0
- data/site/examples/index.html +2907 -0
- data/site/examples/mcp-server/index.html +3018 -0
- data/site/examples/multi-robot-network/index.html +3131 -0
- data/site/examples/rails-application/index.html +3329 -0
- data/site/examples/tool-usage/index.html +3085 -0
- data/site/getting-started/configuration/index.html +3745 -0
- data/site/getting-started/index.html +2572 -0
- data/site/getting-started/installation/index.html +2981 -0
- data/site/getting-started/quick-start/index.html +2942 -0
- data/site/guides/building-robots/index.html +4290 -0
- data/site/guides/creating-networks/index.html +3858 -0
- data/site/guides/index.html +2586 -0
- data/site/guides/mcp-integration/index.html +3581 -0
- data/site/guides/memory/index.html +3586 -0
- data/site/guides/rails-integration/index.html +4019 -0
- data/site/guides/streaming/index.html +3157 -0
- data/site/guides/using-tools/index.html +3802 -0
- data/site/index.html +2671 -0
- data/site/search/search_index.json +1 -0
- data/site/sitemap.xml +183 -0
- data/site/sitemap.xml.gz +0 -0
- data/site/tags.json +1 -0
- data/temp.md +6 -0
- data/tool_manifest_plan.md +155 -0
- metadata +154 -92
- data/docs/examples/rails-application.md +0 -419
- data/docs/guides/ractor-parallelism.md +0 -364
- data/docs/guides/rails-integration.md +0 -681
- data/docs/superpowers/plans/2026-04-14-ractor-integration.md +0 -1538
- data/docs/superpowers/specs/2026-04-14-ractor-integration-design.md +0 -258
- data/lib/generators/robot_lab/install_generator.rb +0 -90
- data/lib/generators/robot_lab/job_generator.rb +0 -40
- data/lib/generators/robot_lab/robot_generator.rb +0 -55
- data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -42
- data/lib/generators/robot_lab/templates/job.rb.tt +0 -21
- data/lib/generators/robot_lab/templates/migration.rb.tt +0 -32
- data/lib/generators/robot_lab/templates/result_model.rb.tt +0 -52
- data/lib/generators/robot_lab/templates/robot.rb.tt +0 -31
- data/lib/generators/robot_lab/templates/robot_job.rb.tt +0 -18
- data/lib/generators/robot_lab/templates/robot_test.rb.tt +0 -34
- data/lib/generators/robot_lab/templates/routing_robot.rb.tt +0 -59
- data/lib/generators/robot_lab/templates/thread_model.rb.tt +0 -40
- data/lib/robot_lab/document_store.rb +0 -155
- data/lib/robot_lab/ractor_boundary.rb +0 -42
- data/lib/robot_lab/ractor_job.rb +0 -37
- data/lib/robot_lab/ractor_memory_proxy.rb +0 -85
- data/lib/robot_lab/ractor_network_scheduler.rb +0 -154
- data/lib/robot_lab/ractor_worker_pool.rb +0 -117
- data/lib/robot_lab/rails_integration/engine.rb +0 -29
- data/lib/robot_lab/rails_integration/job.rb +0 -158
- data/lib/robot_lab/rails_integration/railtie.rb +0 -51
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '020282572c5c4eca7e0c44d60920752df53043df99aa54a2018b68e049404945'
|
|
4
|
+
data.tar.gz: 2f0d0e92ff91a8eb24ff73065e1b91091c57cb6abcf3a0c3349c2370ab877973
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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,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)
|