Skip to content

Architecture Review: Lessons from NanoClaw & OpenFang — Roadmap Recommendations #38

@fengtality

Description

@fengtality

Context

This issue documents findings from a deep architecture review comparing Condor against two peer systems — NanoClaw and OpenFang — alongside OpenClaw. The goal: identify where Condor's architecture lags and what's worth stealing.


TL;DR

Condor is a trading terminal (responds when you ask). The gap to close is becoming a trading agent (works while you sleep). Everything below flows from that.


The Four Systems at a Glance

NanoClaw OpenFang OpenClaw Condor
Language TypeScript Rust TypeScript Python
LOC ~2,000 137,000 ~500,000 ~5,000
Always-on ✅ launchd ✅ daemon ✅ daemon ❌ manual
Persistent memory Per-group CLAUDE.md SQLite v5 + vector + knowledge graph MEMORY.md + daily files condor_bot_data.pickle only
Proactive agents ✅ BackgroundExecutor + Hands ✅ heartbeat + cron
Agent sandboxing ✅ Linux containers ✅ WASM dual-metered ❌ allowlists ❌ none
Loop guard ✅ SHA256, 3-tier
Multi-user ✅ full RBAC ✅ basic flags
Session compaction Manual Auto (block-aware, 80%) Auto + memory flush Manual button only
Skill extensibility Git 3-way merge patches 60 bundled + FangHub + WASM SKILL.md + clawhub None
Audit trail Container logs Merkle hash-chain Session JSONL stdout only

Key Findings

NanoClaw — What's Worth Stealing

1. Per-group/per-user CLAUDE.md memory
NanoClaw gives every group its own CLAUDE.md mounted as the agent's working directory context. The agent reads it at session start and writes to it when asked to remember something. Sessions persist as JSONL in data/sessions/{group}/.

For Condor: every user should have a memory/{user_id}/CLAUDE.md that gets loaded into each ACP session. Currently the agent forgets everything on session end — preferred strategies, risk tolerance, common pairs, past decisions — all gone.

2. Skills as git 3-way merge patches
NanoClaw's skill system is the most sophisticated of the four. Skills carry full modified files, .intent.md metadata, and test suites. Applied via git merge-file against a shared clean base. Conflicts resolved by: git rerere cache → Claude Code → user. Tracked in state.yaml, reproducible via replay.

For Condor: a lighter version — a hands/ directory where Python files following a BaseHand interface are auto-discovered. Each is a self-contained autonomous trading strategy.

3. Container isolation (aspirational)
NanoClaw runs every agent invocation inside a Linux container. Bash is safe because it runs in the container, not on the host. For a trading bot handling real money, OS-level isolation is the right long-term target.


OpenFang — What's Worth Stealing

1. "Hands" — autonomous capability packages
OpenFang's Hands are pre-built autonomous agents that run on schedules without user prompting. Each Hand has a 500+ word expert system prompt, tool requirements, dashboard metrics, and approval gates for sensitive actions.

The Lead Hand example: wakes up daily, discovers prospects, enriches with web research, scores 0–100, deduplicates, delivers qualified leads — zero user interaction required.

The Condor equivalent: a RebalancerHand that wakes up hourly, checks all LP positions, evaluates rebalancing criteria, executes if met, reports to Telegram. This is what perc_sell_rebalancer was manually trying to be.

2. Loop guard (SHA256-based)
OpenFang detects when an agent is stuck calling the same tool with the same parameters:

  • Warn threshold (3): log warning + inject hint to LLM
  • Block threshold (5): refuse the tool call, return error to LLM
  • Circuit breaker (30): terminate the agent loop

Without this, a Condor agent stuck in a get_market_data loop runs for 30 minutes until ACP timeout.

3. Block-aware auto-compaction
OpenFang auto-compacts when the session exceeds 80% of the context window, handling all content block types (Text, ToolUse, ToolResult, Image). Condor's manual "Compact" button needs an automatic fallback.

4. Canonical sessions (cross-session memory)
OpenFang persists a canonical session summary that survives subprocess restarts. When a new ACP session starts, the previous conversation summary is injected into context. Currently in Condor, restarting the agent means starting from zero.

5. Merkle audit trail
Every trade execution logged with a tamper-evident chain (each entry hashes the previous). Eventually mandatory for compliance/tax.


Recommendations — Ordered by Impact

🔴 High Impact

1. Per-user persistent memory

memory/
  {user_id}/
    CLAUDE.md        ← loaded into every agent session for this user
    sessions/
      {session_id}.jsonl

Store: preferred strategies, risk tolerance, common pairs, active positions context, past decisions. Written by the agent, read at session start. Mount as the ACP working directory so claude-agent-acp auto-loads it.

2. Loop guard

class LoopGuard:
    def check(self, tool_name: str, params_hash: str) -> LoopAction:
        # SHA256(tool_name + params) → counter
        # WARN at 3, BLOCK at 5, TERMINATE at 30
        pass

Hook into ACPClient._on_session_update where tool calls are processed. Prevents runaway agent loops — critical for a trading agent.

3. Auto-start + background scheduler

Condor should run as a launchd (macOS) or systemd service. More critically: a BackgroundExecutor that runs configured routines on cron schedules and pushes results to Telegram.

# Example: hourly LP position monitor
@hand(schedule="0 * * * *")
async def lp_monitor(context: HandContext):
    positions = await context.hummingbot.get_positions()
    for pos in positions:
        if pos.needs_rebalance():
            await context.notify(f"⚠️ {pos.pair} needs rebalancing")

4. Canonical session persistence

On ACP session end (graceful or crash), save a summary of the session to the user's CLAUDE.md. New sessions pick up where the last one left off. Eliminates the "agent forgot everything" problem.


🟡 Medium Impact

5. Autonomous trading routines as "Hands"

Elevate routines/ to first-class. Pre-built autonomous strategies that run without user prompting:

  • lp_rebalancer_hand.py — monitor and rebalance LP positions
  • price_alert_hand.py — alert on price thresholds
  • pnl_report_hand.py — daily P&L summary pushed to Telegram
  • risk_monitor_hand.py — alert when position exceeds risk threshold

Each Hand: a Python class with schedule, system_prompt, tools, and on_trigger().

6. Response delivery guarantee

Current bug: agent completes its work, TelegramStreamer._flush_edit fails, response silently dropped. Fix: fall back to send_message if edit_message_text fails.

try:
    await bot.edit_message_text(chat_id=chat_id, message_id=msg_id, text=final_text)
except BadRequest as e:
    if "message is not modified" not in str(e):
        # Never drop the response silently
        await bot.send_message(chat_id=chat_id, text=final_text)
        log.error("edit failed, fell back to send_message: %s", e)

7. Auto-compaction

Trigger compaction automatically when context exceeds ~75% of the window. Use block-aware compaction — handle ToolUse/ToolResult pairs correctly, never split them.


🟢 Lower Impact / Future

8. Structured RBAC

Current OWNER/TRADER flags are too coarse. A capability system: "view-only", "trade testnet only", "trade up to $X", "no LP operations".

9. Merkle audit trail for trades

Tamper-evident log of all executed trades and position changes. Required for serious compliance/tax use.

10. WASM sandbox for user strategies

When users contribute trading strategies, run them in a WASM sandbox (like OpenFang) to prevent credential access or unexpected API calls.


The Core Insight

All four systems assume a human is in the loop. The biggest architectural gap in Condor vs OpenFang is autonomous operation. OpenFang's Hands wake up and work while you sleep. Condor waits for you to type.

For a trading bot, this is backwards. The whole point is 24/7 monitoring, not waiting for the user to ask "how are my positions doing?"

The first feature to build: a BackgroundExecutor that runs configured routines on cron schedules and pushes results to Telegram. This single feature would transform Condor from a trading terminal into a trading agent.


References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions