Files
evotraders/docs/legacy-inventory.md
cillin 16b54d5ccc feat(agent): complete EvoAgent integration for all 6 agent roles
Migrate all agent roles from Legacy to EvoAgent architecture:
- fundamentals_analyst, technical_analyst, sentiment_analyst, valuation_analyst
- risk_manager, portfolio_manager

Key changes:
- EvoAgent now supports Portfolio Manager compatibility methods (_make_decision,
  get_decisions, get_portfolio_state, load_portfolio_state, update_portfolio)
- Add UnifiedAgentFactory for centralized agent creation
- ToolGuard with batch approval API and WebSocket broadcast
- Legacy agents marked deprecated (AnalystAgent, RiskAgent, PMAgent)
- Remove backend/agents/compat.py migration shim
- Add run_id alongside workspace_id for semantic clarity
- Complete integration test coverage (13 tests)
- All smoke tests passing for 6 agent roles

Constraint: Must maintain backward compatibility with existing run configs
Constraint: Memory support must work with EvoAgent (no fallback to Legacy)
Rejected: Separate PM implementation for EvoAgent | unified approach cleaner
Confidence: high
Scope-risk: broad
Directive: EVO_AGENT_IDS env var still respected but defaults to all roles
Not-tested: Kubernetes sandbox mode for skill execution
2026-04-02 00:55:08 +08:00

8.6 KiB

Legacy Inventory

This file records the major legacy or compatibility-oriented surfaces that still exist in the repository.

It is not a deletion plan by itself. Its purpose is to separate:

  • current source-of-truth runtime paths
  • intentional compatibility surfaces
  • historical directories and scripts that should not guide new development

Source Of Truth

These are the current defaults to build against:

  • runs/<run_id>/
    • runtime state, bootstrap configuration, agent runtime assets, logs
  • split services
    • backend.apps.agent_service on :8000
    • backend.apps.runtime_service on :8003
    • backend.apps.trading_service on :8001
    • backend.apps.news_service on :8002
  • gateway process
    • backend.main
    • backend.services.gateway on :8765

Compatibility Surface Classification

All compatibility surfaces are categorized into three buckets:

1. Stable and Intentional (Keep)

These have clear operational reasons to exist and are documented as intentional compatibility surfaces with explicit ownership.

Surface Location Owner Reason
Gateway-first production scripts/run_prod.sh, deploy/systemd/, deploy/nginx/ ops-team Current production example runs gateway directly and proxies /ws
Dashboard export layer runs/<run_id>/team_dashboard/*.json frontend-team Downstream dashboard consumers read these exports
Design-time workspace registry workspaces/, backend.api.workspaces control-plane-team Control-plane editing and registry-style management
Gateway WebSocket transport backend.services.gateway on :8765 runtime-team Live event streaming contract for frontend

Status: These are NOT migration leftovers. Do not remove without explicit replacement plan signed off by owning team.

2. Temporary and Shrinking (Mark for Removal)

These should not grow further. Keep only until concrete replacement is fully in use.

Surface Location Replacement ETA
Legacy analyst agents backend.agents.analyst.* EvoAgent After EvoAgent smoke tests pass
Mixed workspace_id semantics /api/workspaces/{id}/agents/... Explicit run_id vs workspace_id routes TBD
Root-level runtime directories live/, backtest/, production/ runs/<run_id>/ Already deprecated, safe to ignore

Status: Do not add new code using these surfaces. Migrate existing usage when touching related code.

3. Deferred Until Topology Final (Revisit Later)

These are real migration boundaries, but removing them prematurely would create churn without simplifying the current runtime. Revisit only after production topology and service-routing policy are frozen.

Surface Current State Decision Needed
OpenClaw dual integration REST facade (:8004) + Gateway WebSocket (:18789) Which surface is the long-term contract?
Env-dependent service fallbacks TRADING_SERVICE_URL, NEWS_SERVICE_URL fallbacks to local modules Remove fallbacks and require explicit URLs?
Split-service production deploy Docs show gateway-first, dev uses split-service Align production with dev topology?

Status: Document current behavior. Do not actively remove until topology decisions are finalized.

Detailed Surface Documentation

Gateway-First Production Example

Files:

  • scripts/run_prod.sh - Production launch script
  • deploy/systemd/evotraders.service - systemd unit
  • deploy/nginx/bigtime.cillinn.com.conf - HTTPS + WebSocket proxy
  • deploy/nginx/bigtime.cillinn.com.http.conf - HTTP variant

Behavior:

# scripts/run_prod.sh launches:
python3 -m backend.main \
  --mode live \
  --config-name production \
  --host 127.0.0.1 \
  --port 8765

nginx proxies:

  • /ws -> 127.0.0.1:8765 (WebSocket upgrade)
  • / -> static files in /var/www/bigtime/current

Why this exists:

  • Simpler production deployment (single process + nginx)
  • WebSocket is the practical live event contract for frontend
  • Split-service topology adds operational complexity not needed for all deployments

Ownership: ops-team Status: Stable and intentional

OpenClaw Dual Integration

Two different integration surfaces exist for OpenClaw:

A. REST Facade (Port 8004)

File: backend/apps/openclaw_service.py Routes: backend/api/openclaw.py (prefix /api/openclaw)

Purpose:

  • Read-only OpenClaw CLI integration
  • Typed Pydantic models for all responses
  • Direct HTTP/REST access to OpenClaw state

Use when:

  • You need typed, stable API contracts
  • You want to poll OpenClaw status from external systems
  • You need programmatic access without WebSocket complexity

Example:

curl http://localhost:8004/api/openclaw/status

B. Gateway WebSocket Integration (Port 18789)

Files:

  • backend/services/gateway_openclaw_handlers.py
  • shared/client/openclaw_websocket_client.py

Purpose:

  • Real-time bidirectional communication with OpenClaw
  • Event streaming and live updates
  • Integration with Gateway event flow

Use when:

  • You need real-time updates
  • You're already connected to Gateway WebSocket
  • You want event-driven rather than polling architecture

Example:

// Frontend connects to ws://localhost:18789
const ws = new WebSocket('ws://localhost:18789');

Key Differences

Aspect REST Facade (8004) Gateway WebSocket (18789)
Protocol HTTP/REST WebSocket
Access pattern Request/response Event-driven
Typing Pydantic models JSON messages
Real-time Polling required Push notifications
Use case External integrations, scripts Frontend, live dashboards
Stability Higher (explicit contracts) Evolving with Gateway

Decision needed: Which surface becomes the long-term contract?

  • REST facade is more stable but read-only
  • WebSocket integration is more capable but tied to Gateway evolution

Ownership: runtime-team Status: Deferred until topology final

Dashboard Export Layer

Files: runs/<run_id>/team_dashboard/*.json

Purpose:

  • Compatibility/export layer for dashboard consumers
  • Non-authoritative snapshot of runtime state
  • Can be disabled via ENABLE_DASHBOARD_COMPAT_EXPORTS=false

Why not remove:

  • Downstream consumers still read these files
  • Provides decoupling between runtime and dashboard

Ownership: frontend-team Status: Stable and intentional

Design-Time Workspace Registry

Files:

  • workspaces/ directory
  • backend/api/workspaces.py
  • backend/agents/workspace_manager.py

Purpose:

  • Control-plane editing and registry-style management
  • Design-time CRUD for agent workspaces
  • Separate from runtime state in runs/<run_id>/

Key distinction:

  • workspaces/ = design-time registry (what agents could be)
  • runs/<run_id>/ = runtime state (what agents are right now)

Ownership: control-plane-team Status: Stable and intentional

Historical Or High-Risk-To-Misread Surfaces

These remain in the tree, but they should not define the architecture for new work.

Root-level runtime directories

  • live/
  • backtest/
  • production/

Read:

  • treat these as historical or compatibility-oriented data/layout artifacts
  • do not use them as the default runtime contract for new features

Mixed workspace_id semantics on agent routes

  • /api/workspaces/{workspace_id}/agents/...

Read:

  • design-time CRUD routes use workspace_id as a registry workspace id
  • profile, skills, and editable file routes use workspace_id as a run id

Mitigation already in repo:

  • agent_service /api/status exposes scope metadata
  • runtime-read responses expose scope_type and scope_note

Partial EvoAgent rollout

  • EVO_AGENT_IDS
  • staged smoke coverage in scripts/smoke_evo_runtime.py

Read:

  • EvoAgent is still a controlled rollout path
  • legacy analyst/risk/PM implementations remain the default runtime path for now

When in doubt:

  1. trust docs/current-architecture.md
  2. trust runs/<run_id>/ over root-level runtime directories
  3. treat workspaces/ as control-plane registry, not runtime truth
  4. treat deploy artifacts as the current checked-in example, not the full system contract
  5. check this file's Compatibility Surface Classification before assuming something is legacy

Change Log

Date Change
2026-03-31 Added Compatibility Surface Classification (3 buckets)
2026-03-31 Documented OpenClaw dual integration (REST vs WebSocket)
2026-03-31 Added ownership and status to all surfaces