Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/bali-zero_teman2.json
T

1 line
121 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "bali-zero/teman2", "files": {"agent-library/scar_replay/world-scan-run.sh": {"9e8bb6055c42e72817fc7b01bc5035a2a7b7bf41": {"t": 1785745959.425854, "n": 8335, "h": "1d26bad6606b7ab9", "c": "#!/bin/bash\n# world-scan-run.sh — weekly external failure-pattern scan for the evolver.\n#\n# Reuse-first (2026-06-04): forked from ~/scripts/wr2-external-bench-run.sh.\n# ~80% reused (multi-LLM ingest+extract via a Claude agent, DeepSeek translate\n# via world_scan_translate.py, devils-advocate-style gate built into the\n# translator's deterministic grade, _proposed/ staging, Telegram). The only NEW\n# code is world_scan_translate.py (pattern -> draft executable probe).\n#\n# Pipeline:\n# 1. INGEST+EXTRACT (Claude Opus agent w/ web search): scan SRE/security/\n# agent-failure sources -> JSON list of failure patterns.\n# 2. TRANSLATE (world_scan_translate.py + DeepSeek): each pattern -> draft probe\n# with a DETERMINISTIC executability gate (ADOPT/OBSERVE/REJECT).\n# 3. STAGE: write drafts to research/operations/_proposed/<date>-world-scan.md.\n# 4. NOTIFY: Telegram summary to Antonello. NEVER auto-merge; human promotes\n# an ADOPT draft into scar_probes.py by hand.\n#\n# Cron: weekly (1st-of-week guard inside). Schedule via LaunchAgent.\n# Cost: ~$0.05/week (Gemini/Claude OAuth + DeepSeek translate calls).\n\nset -euo pipefail\n\nLOGDIR=\"${HOME}/logs\"; mkdir -p \"$LOGDIR\"\nLOG=\"$LOGDIR/world-scan.log\"\nERR=\"$LOGDIR/world-scan.err.log\"\n\nHARNESS_DIR=\"${SCAR_REPLAY_DIR:-${HOME}/nuzantara-deploy/agent-library/scar_replay}\"\nREPO_ROOT=\"${WORLD_SCAN_REPO_ROOT:-${HOME}/nuzantara-deploy}\"\nWEEK_TAG=\"$(date +%Y-W%V)\"\nPROPOSED_DIR=\"${REPO_ROOT}/research/operations/_proposed\"\nOUTPUT_FILE=\"${PROPOSED_DIR}/${WEEK_TAG}-world-scan-probes.md\"\nPATTERNS_JSON=\"/tmp/world-scan-patterns-${WEEK_TAG}.json\"\n\nlog() { echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*\" >> \"$LOG\"; }\n\n# telegram_alert: reused verbatim from scar-replay-run.sh (#1090). Resolves token\n# + chat id from sanctioned vaults; tolerates OWNER vs APPROVAL chat-id naming\n# drift; suppresses silently if creds unresolved (Law 4 — never block on outage).\ntelegram_alert() {\n local msg=\"$1\"\n local tok=\"${TELEGRAM_BOT_TOKEN:-}\"\n local chat=\"${TELEGRAM_OWNER_CHAT_ID:-${TELEGRAM_APPROVAL_CHAT_ID:-}}\"\n if [[ -z \"${tok}\" || -z \"${chat}\" ]]; then\n for f in \"${HOME}/.nuzantara-secrets.env\" \"${HOME}/.openclaw/workspace/.env.master\"; do\n [[ -f \"$f\" ]] || continue\n [[ -z \"${tok}\" ]] && tok=\"$(grep -m1 -E '^TELEGRAM_BOT_TOKEN=' \"$f\" 2>/dev/null | cut -d= -f2- | tr -d '\"')\"\n [[ -z \"${chat}\" ]] && chat=\"$(grep -m1 -E '^TELEGRAM_(OWNER|APPROVAL)_CHAT_ID=' \"$f\" 2>/dev/null | cut -d= -f2- | tr -d '\"')\"\n done\n fi\n if [[ -z \"${tok}\" || -z \"${chat}\" ]]; then\n log \"WARN: telegram creds unresolved — human-alert suppressed: ${msg}\"\n return 0\n fi\n curl -sS --max-time 20 -X POST \"https://api.telegram.org/bot${tok}/sendMessage\" \\\n -d \"chat_id=${chat}\" -d \"text=${msg}\" >/dev/null 2>&1 || true\n}\n\nlog \"world-scan starting (week=${WEEK_TAG}, out=${OUTPUT_FILE})\"\n\n# --- idempotence: one scan per week ---\nif [ -s \"$OUTPUT_FILE\" ]; then\n log \"skip: ${OUTPUT_FILE} already exists ($(wc -l < \"$OUTPUT_FILE\") lines). Delete to re-run.\"\n exit 0\nfi\n\n# --- worktree-isolation guard (same discipline as scar-replay-run.sh): never\n# run from inside the shared deploy worktree ---\ncase \"$(pwd -P)/\" in\n \"${REPO_ROOT}/\"*) log \"REFUSE: cwd inside shared deploy worktree; aborting.\"; exit 0 ;;\nesac\n\n# --- secrets: DEEPSEEK_API_KEY (with vault drift fallback) + telegram ---\nDS_KEY=\"${DEEPSEEK_API_KEY:-}\"\nif [ -z \"$DS_KEY\" ]; then\n for f in \"${HOME}/.nuzantara-secrets.env\" \"${HOME}/.openclaw/workspace/.env.master\"; do\n [ -f \"$f\" ] || continue\n line=$(grep -m1 -E '^DEEPSEEK_API_KEY=' \"$f\" 2>/dev/null || true)\n [ -n \"$line\" ] && { DS_KEY=\"${line#DEEPSEEK_API_KEY=}\"; DS_KEY=\"${DS_KEY%\\\"}\"; DS_KEY=\"${DS_KEY#\\\"}\"; break; }\n done\nfi\nif [ -z \"$DS_KEY\" ]; then\n log \"FATAL: DEEPSEEK_API_KEY not found in any vault — cannot translate. Aborting.\"\n exit 2\nfi\nexport DEEPSEEK_API_KEY=\"$DS_KEY\"\n\nmkdir -p \"$PROPOSED_DIR\"\n\n# --- Step 1: INGEST + EXTRACT via Claude Opus agent (OAuth-only, web search) ---\n# Reuse of the wr2-external-bench invocation shape. The agent does the web\n# research and emits a strict JSON array of failure patterns to PATTERNS_JSON.\nINGEST_PROMPT=\"You are world-scan, the evolver's external research scout.\n\nResearch the LAST ~30 days of public best-practices and post-mortems on:\n - SRE / reliability engineering (toil, retries, idempotency, locking, queues)\n - chaos engineering & fault injection\n - autonomous-agent / LLM-agent failure modes (loops, drift, tool misuse, state)\n - CI/CD & git-worktree / deploy hazards\nUse web search. Prefer concrete engineering write-ups (incident reports, SRE\nbooks/blogs, postmortems), NOT listicles.\n\nExtract 6-12 DISTINCT failure patterns relevant to a self-improving ops agent\nthat runs local git worktrees, LaunchAgent cron, shell scripts, Postgres.\n\nWrite ONLY a strict JSON array to ${PATTERNS_JSON}, each item:\n {\\\"title\\\": \\\"...\\\", \\\"text\\\": \\\"2-4 sentence description of the failure mode and why it bites\\\", \\\"source\\\": \\\"url or outlet\\\"}\nNo prose around the JSON. Reject vague/cultural advice — only concrete, testable failure mechanics.\"\n\nCLAUDE_BIN=\"${HOME}/.local/bin/claude\"; [ -x \"$CLAUDE_BIN\" ] || CLAUDE_BIN=\"/opt/homebrew/bin/claude\"\n\nlog \"step1: ingest+extract via claude opus (web search)\"\ntimeout 1800 \"$CLAUDE_BIN\" -p \\\n --model claude-opus-4-8 \\\n --permission-mode bypassPermissions \\\n --max-budget-usd \"${WORLD_SCAN_MAX_BUDGET_USD:-5}\" \\\n \"$INGEST_PROMPT\" >> \"$LOG\" 2>> \"$ERR\" || log \"WARN: ingest agent exit=$?\"\n\nif [ ! -s \"$PATTERNS_JSON\" ]; then\n log \"FATAL: no patterns JSON produced at ${PATTERNS_JSON}. Aborting.\"\n # Telegram: this needs a human (ingest produced nothing).\n telegram_alert \"⚠️ world-scan ${WEEK_TAG}: ingest produced no patterns. Check ${ERR}.\"\n exit 3\nfi\nlog \"step1 done: $(wc -c < \"$PATTERNS_JSON\") bytes of patterns\"\n\n# --- Step 2+3: TRANSLATE each pattern + STAGE drafts ---\nlog \"step2: translate patterns -> draft probes (DeepSeek + deterministic gate)\"\nPYTHONPATH=\"${HARNESS_DIR}\" python3 - \"$PATTERNS_JSON\" \"$OUTPUT_FILE\" \"$WEEK_TAG\" <<'PYEOF' >> \"$LOG\" 2>> \"$ERR\"\nimport json, sys, os, datetime\nsys.path.insert(0, os.environ[\"PYTHONPATH\"])\nimport world_scan_translate as wt\n\npatterns_path, out_path, week = sys.argv[1], sys.argv[2], sys.argv[3]\nkey = os.environ[\"DEEPSEEK_API_KEY\"]\npatterns = json.load(open(patterns_path))\nif not isinstance(patterns, list):\n print(\"patterns JSON is not a list — abort\"); sys.exit(4)\n\ndrafts = []\nfor p in patterns:\n title = (p.get(\"title\") or \"untitled\").strip()\n text = (p.get(\"text\") or \"\") + \"\\nSource: \" + (p.get(\"source\") or \"\")\n d = wt.translate_pattern(key, title, text)\n d.source_refs = p.get(\"source\") or title\n drafts.append(d)\n\nadopt = [d for d in drafts if d.category == \"ADOPT\"]\nobserve = [d for d in drafts if d.category == \"OBSERVE\"]\nreject = [d for d in drafts if d.category == \"REJECT\"]\n\nheader = (\n f\"# World-Scan draft probes — {week}\\n\\n\"\n f\"> Auto-generated by world-scan (reuse-first fork of wr2-external-bench). \"\n f\"These are DRAFT replay-probes proposed from external failure patterns. \"\n f\"**Nothing here is live.** A human promotes an ADOPT draft into \"\n f\"`agent-library/scar_replay/scar_probes.py` by hand (fixture + assertion as \"\n f\"code) and commits it. Never auto-merged (Law 5).\\n\\n\"\n f\"**Summary:** {len(adopt)} ADOPT · {len(observe)} OBSERVE · {len(reject)} REJECT \"\n f\"(of {len(drafts)} patterns scanned).\\n\\n---\\n\\n\"\n)\nbody = \"\".join(wt.render_draft_md(d) for d in (adopt + observe + reject))\nopen(out_path, \"w\").write(header + body)\nprint(f\"WORLD_SCAN_SUMMARY adopt={len(adopt)} observe={len(observe)} reject={len(reject)} total={len(drafts)}\")\nPYEOF\n\nif [ ! -s \"$OUTPUT_FILE\" ]; then\n log \"FATAL: translation produced no output file. Check ${ERR}.\"\n telegram_alert \"⚠️ world-scan ${WEEK_TAG}: translation failed. Check ${ERR}.\"\n exit 5\nfi\n\nSUMMARY=$(grep -h \"WORLD_SCAN_SUMMARY\" \"$LOG\" | tail -1 || echo \"summary unavailable\")\nlog \"step3 done: ${OUTPUT_FILE} ($(wc -l < \"$OUTPUT_FILE\") lines) — ${SUMMARY}\"\n\n# --- Step 4: notify (human reviews; never auto-merge) ---\ntelegram_alert \"🌐 world-scan ${WEEK_TAG} done. ${SUMMARY}. Draft probes staged at research/operations/_proposed/${WEEK_TAG}-world-scan-probes.md — review & promote ADOPT drafts by hand.\"\nlog \"DONE world-scan ${WEEK_TAG}\"\nexit 0\n"}, "c43b22330652a365d9fbe32ca1e5e8cdb03c8e23": {"t": 1785758294.8416717, "n": 8335, "h": "1d26bad6606b7ab9", "c": "#!/bin/bash\n# world-scan-run.sh — weekly external failure-pattern scan for the evolver.\n#\n# Reuse-first (2026-06-04): forked from ~/scripts/wr2-external-bench-run.sh.\n# ~80% reused (multi-LLM ingest+extract via a Claude agent, DeepSeek translate\n# via world_scan_translate.py, devils-advocate-style gate built into the\n# translator's deterministic grade, _proposed/ staging, Telegram). The only NEW\n# code is world_scan_translate.py (pattern -> draft executable probe).\n#\n# Pipeline:\n# 1. INGEST+EXTRACT (Claude Opus agent w/ web search): scan SRE/security/\n# agent-failure sources -> JSON list of failure patterns.\n# 2. TRANSLATE (world_scan_translate.py + DeepSeek): each pattern -> draft probe\n# with a DETERMINISTIC executability gate (ADOPT/OBSERVE/REJECT).\n# 3. STAGE: write drafts to research/operations/_proposed/<date>-world-scan.md.\n# 4. NOTIFY: Telegram summary to Antonello. NEVER auto-merge; human promotes\n# an ADOPT draft into scar_probes.py by hand.\n#\n# Cron: weekly (1st-of-week guard inside). Schedule via LaunchAgent.\n# Cost: ~$0.05/week (Gemini/Claude OAuth + DeepSeek translate calls).\n\nset -euo pipefail\n\nLOGDIR=\"${HOME}/logs\"; mkdir -p \"$LOGDIR\"\nLOG=\"$LOGDIR/world-scan.log\"\nERR=\"$LOGDIR/world-scan.err.log\"\n\nHARNESS_DIR=\"${SCAR_REPLAY_DIR:-${HOME}/nuzantara-deploy/agent-library/scar_replay}\"\nREPO_ROOT=\"${WORLD_SCAN_REPO_ROOT:-${HOME}/nuzantara-deploy}\"\nWEEK_TAG=\"$(date +%Y-W%V)\"\nPROPOSED_DIR=\"${REPO_ROOT}/research/operations/_proposed\"\nOUTPUT_FILE=\"${PROPOSED_DIR}/${WEEK_TAG}-world-scan-probes.md\"\nPATTERNS_JSON=\"/tmp/world-scan-patterns-${WEEK_TAG}.json\"\n\nlog() { echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*\" >> \"$LOG\"; }\n\n# telegram_alert: reused verbatim from scar-replay-run.sh (#1090). Resolves token\n# + chat id from sanctioned vaults; tolerates OWNER vs APPROVAL chat-id naming\n# drift; suppresses silently if creds unresolved (Law 4 — never block on outage).\ntelegram_alert() {\n local msg=\"$1\"\n local tok=\"${TELEGRAM_BOT_TOKEN:-}\"\n local chat=\"${TELEGRAM_OWNER_CHAT_ID:-${TELEGRAM_APPROVAL_CHAT_ID:-}}\"\n if [[ -z \"${tok}\" || -z \"${chat}\" ]]; then\n for f in \"${HOME}/.nuzantara-secrets.env\" \"${HOME}/.openclaw/workspace/.env.master\"; do\n [[ -f \"$f\" ]] || continue\n [[ -z \"${tok}\" ]] && tok=\"$(grep -m1 -E '^TELEGRAM_BOT_TOKEN=' \"$f\" 2>/dev/null | cut -d= -f2- | tr -d '\"')\"\n [[ -z \"${chat}\" ]] && chat=\"$(grep -m1 -E '^TELEGRAM_(OWNER|APPROVAL)_CHAT_ID=' \"$f\" 2>/dev/null | cut -d= -f2- | tr -d '\"')\"\n done\n fi\n if [[ -z \"${tok}\" || -z \"${chat}\" ]]; then\n log \"WARN: telegram creds unresolved — human-alert suppressed: ${msg}\"\n return 0\n fi\n curl -sS --max-time 20 -X POST \"https://api.telegram.org/bot${tok}/sendMessage\" \\\n -d \"chat_id=${chat}\" -d \"text=${msg}\" >/dev/null 2>&1 || true\n}\n\nlog \"world-scan starting (week=${WEEK_TAG}, out=${OUTPUT_FILE})\"\n\n# --- idempotence: one scan per week ---\nif [ -s \"$OUTPUT_FILE\" ]; then\n log \"skip: ${OUTPUT_FILE} already exists ($(wc -l < \"$OUTPUT_FILE\") lines). Delete to re-run.\"\n exit 0\nfi\n\n# --- worktree-isolation guard (same discipline as scar-replay-run.sh): never\n# run from inside the shared deploy worktree ---\ncase \"$(pwd -P)/\" in\n \"${REPO_ROOT}/\"*) log \"REFUSE: cwd inside shared deploy worktree; aborting.\"; exit 0 ;;\nesac\n\n# --- secrets: DEEPSEEK_API_KEY (with vault drift fallback) + telegram ---\nDS_KEY=\"${DEEPSEEK_API_KEY:-}\"\nif [ -z \"$DS_KEY\" ]; then\n for f in \"${HOME}/.nuzantara-secrets.env\" \"${HOME}/.openclaw/workspace/.env.master\"; do\n [ -f \"$f\" ] || continue\n line=$(grep -m1 -E '^DEEPSEEK_API_KEY=' \"$f\" 2>/dev/null || true)\n [ -n \"$line\" ] && { DS_KEY=\"${line#DEEPSEEK_API_KEY=}\"; DS_KEY=\"${DS_KEY%\\\"}\"; DS_KEY=\"${DS_KEY#\\\"}\"; break; }\n done\nfi\nif [ -z \"$DS_KEY\" ]; then\n log \"FATAL: DEEPSEEK_API_KEY not found in any vault — cannot translate. Aborting.\"\n exit 2\nfi\nexport DEEPSEEK_API_KEY=\"$DS_KEY\"\n\nmkdir -p \"$PROPOSED_DIR\"\n\n# --- Step 1: INGEST + EXTRACT via Claude Opus agent (OAuth-only, web search) ---\n# Reuse of the wr2-external-bench invocation shape. The agent does the web\n# research and emits a strict JSON array of failure patterns to PATTERNS_JSON.\nINGEST_PROMPT=\"You are world-scan, the evolver's external research scout.\n\nResearch the LAST ~30 days of public best-practices and post-mortems on:\n - SRE / reliability engineering (toil, retries, idempotency, locking, queues)\n - chaos engineering & fault injection\n - autonomous-agent / LLM-agent failure modes (loops, drift, tool misuse, state)\n - CI/CD & git-worktree / deploy hazards\nUse web search. Prefer concrete engineering write-ups (incident reports, SRE\nbooks/blogs, postmortems), NOT listicles.\n\nExtract 6-12 DISTINCT failure patterns relevant to a self-improving ops agent\nthat runs local git worktrees, LaunchAgent cron, shell scripts, Postgres.\n\nWrite ONLY a strict JSON array to ${PATTERNS_JSON}, each item:\n {\\\"title\\\": \\\"...\\\", \\\"text\\\": \\\"2-4 sentence description of the failure mode and why it bites\\\", \\\"source\\\": \\\"url or outlet\\\"}\nNo prose around the JSON. Reject vague/cultural advice — only concrete, testable failure mechanics.\"\n\nCLAUDE_BIN=\"${HOME}/.local/bin/claude\"; [ -x \"$CLAUDE_BIN\" ] || CLAUDE_BIN=\"/opt/homebrew/bin/claude\"\n\nlog \"step1: ingest+extract via claude opus (web search)\"\ntimeout 1800 \"$CLAUDE_BIN\" -p \\\n --model claude-opus-4-8 \\\n --permission-mode bypassPermissions \\\n --max-budget-usd \"${WORLD_SCAN_MAX_BUDGET_USD:-5}\" \\\n \"$INGEST_PROMPT\" >> \"$LOG\" 2>> \"$ERR\" || log \"WARN: ingest agent exit=$?\"\n\nif [ ! -s \"$PATTERNS_JSON\" ]; then\n log \"FATAL: no patterns JSON produced at ${PATTERNS_JSON}. Aborting.\"\n # Telegram: this needs a human (ingest produced nothing).\n telegram_alert \"⚠️ world-scan ${WEEK_TAG}: ingest produced no patterns. Check ${ERR}.\"\n exit 3\nfi\nlog \"step1 done: $(wc -c < \"$PATTERNS_JSON\") bytes of patterns\"\n\n# --- Step 2+3: TRANSLATE each pattern + STAGE drafts ---\nlog \"step2: translate patterns -> draft probes (DeepSeek + deterministic gate)\"\nPYTHONPATH=\"${HARNESS_DIR}\" python3 - \"$PATTERNS_JSON\" \"$OUTPUT_FILE\" \"$WEEK_TAG\" <<'PYEOF' >> \"$LOG\" 2>> \"$ERR\"\nimport json, sys, os, datetime\nsys.path.insert(0, os.environ[\"PYTHONPATH\"])\nimport world_scan_translate as wt\n\npatterns_path, out_path, week = sys.argv[1], sys.argv[2], sys.argv[3]\nkey = os.environ[\"DEEPSEEK_API_KEY\"]\npatterns = json.load(open(patterns_path))\nif not isinstance(patterns, list):\n print(\"patterns JSON is not a list — abort\"); sys.exit(4)\n\ndrafts = []\nfor p in patterns:\n title = (p.get(\"title\") or \"untitled\").strip()\n text = (p.get(\"text\") or \"\") + \"\\nSource: \" + (p.get(\"source\") or \"\")\n d = wt.translate_pattern(key, title, text)\n d.source_refs = p.get(\"source\") or title\n drafts.append(d)\n\nadopt = [d for d in drafts if d.category == \"ADOPT\"]\nobserve = [d for d in drafts if d.category == \"OBSERVE\"]\nreject = [d for d in drafts if d.category == \"REJECT\"]\n\nheader = (\n f\"# World-Scan draft probes — {week}\\n\\n\"\n f\"> Auto-generated by world-scan (reuse-first fork of wr2-external-bench). \"\n f\"These are DRAFT replay-probes proposed from external failure patterns. \"\n f\"**Nothing here is live.** A human promotes an ADOPT draft into \"\n f\"`agent-library/scar_replay/scar_probes.py` by hand (fixture + assertion as \"\n f\"code) and commits it. Never auto-merged (Law 5).\\n\\n\"\n f\"**Summary:** {len(adopt)} ADOPT · {len(observe)} OBSERVE · {len(reject)} REJECT \"\n f\"(of {len(drafts)} patterns scanned).\\n\\n---\\n\\n\"\n)\nbody = \"\".join(wt.render_draft_md(d) for d in (adopt + observe + reject))\nopen(out_path, \"w\").write(header + body)\nprint(f\"WORLD_SCAN_SUMMARY adopt={len(adopt)} observe={len(observe)} reject={len(reject)} total={len(drafts)}\")\nPYEOF\n\nif [ ! -s \"$OUTPUT_FILE\" ]; then\n log \"FATAL: translation produced no output file. Check ${ERR}.\"\n telegram_alert \"⚠️ world-scan ${WEEK_TAG}: translation failed. Check ${ERR}.\"\n exit 5\nfi\n\nSUMMARY=$(grep -h \"WORLD_SCAN_SUMMARY\" \"$LOG\" | tail -1 || echo \"summary unavailable\")\nlog \"step3 done: ${OUTPUT_FILE} ($(wc -l < \"$OUTPUT_FILE\") lines) — ${SUMMARY}\"\n\n# --- Step 4: notify (human reviews; never auto-merge) ---\ntelegram_alert \"🌐 world-scan ${WEEK_TAG} done. ${SUMMARY}. Draft probes staged at research/operations/_proposed/${WEEK_TAG}-world-scan-probes.md — review & promote ADOPT drafts by hand.\"\nlog \"DONE world-scan ${WEEK_TAG}\"\nexit 0\n"}, "b005f859986dd37a17383d49a5bf3ac12f09c7e3": {"t": 1785758296.270696, "n": 8280, "h": "45bbfea04af649db", "c": "#!/bin/bash\n# world-scan-run.sh — weekly external failure-pattern scan for the evolver.\n#\n# Reuse-first (2026-06-04): forked from ~/scripts/wr2-external-bench-run.sh.\n# ~80% reused (multi-LLM ingest+extract via a Claude agent, DeepSeek translate\n# via world_scan_translate.py, devils-advocate-style gate built into the\n# translator's deterministic grade, _proposed/ staging, Telegram). The only NEW\n# code is world_scan_translate.py (pattern -> draft executable probe).\n#\n# Pipeline:\n# 1. INGEST+EXTRACT (Claude Opus agent w/ web search): scan SRE/security/\n# agent-failure sources -> JSON list of failure patterns.\n# 2. TRANSLATE (world_scan_translate.py + DeepSeek): each pattern -> draft probe\n# with a DETERMINISTIC executability gate (ADOPT/OBSERVE/REJECT).\n# 3. STAGE: write drafts to research/operations/_proposed/<date>-world-scan.md.\n# 4. NOTIFY: Telegram summary to Antonello. NEVER auto-merge; human promotes\n# an ADOPT draft into scar_probes.py by hand.\n#\n# Cron: weekly (1st-of-week guard inside). Schedule via LaunchAgent.\n# Cost: ~$0.05/week (Gemini/Claude OAuth + DeepSeek translate calls).\n\nset -euo pipefail\n\nLOGDIR=\"${HOME}/logs\"; mkdir -p \"$LOGDIR\"\nLOG=\"$LOGDIR/world-scan.log\"\nERR=\"$LOGDIR/world-scan.err.log\"\n\nHARNESS_DIR=\"${SCAR_REPLAY_DIR:-${HOME}/nuzantara-deploy/agent-library/scar_replay}\"\nREPO_ROOT=\"${WORLD_SCAN_REPO_ROOT:-${HOME}/nuzantara-deploy}\"\nWEEK_TAG=\"$(date +%Y-W%V)\"\nPROPOSED_DIR=\"${REPO_ROOT}/research/operations/_proposed\"\nOUTPUT_FILE=\"${PROPOSED_DIR}/${WEEK_TAG}-world-scan-probes.md\"\nPATTERNS_JSON=\"/tmp/world-scan-patterns-${WEEK_TAG}.json\"\n\nlog() { echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*\" >> \"$LOG\"; }\n\n# telegram_alert: reused verbatim from scar-replay-run.sh (#1090). Resolves token\n# + chat id from sanctioned vaults; tolerates OWNER vs APPROVAL chat-id naming\n# drift; suppresses silently if creds unresolved (Law 4 — never block on outage).\ntelegram_alert() {\n local msg=\"$1\"\n local tok=\"${TELEGRAM_BOT_TOKEN:-}\"\n local chat=\"${TELEGRAM_OWNER_CHAT_ID:-${TELEGRAM_APPROVAL_CHAT_ID:-}}\"\n if [[ -z \"${tok}\" || -z \"${chat}\" ]]; then\n for f in \"${HOME}/.nuzantara-secrets.env\" \"${HOME}/.openclaw/workspace/.env.master\"; do\n [[ -f \"$f\" ]] || continue\n [[ -z \"${tok}\" ]] && tok=\"$(grep -m1 -E '^TELEGRAM_BOT_TOKEN=' \"$f\" 2>/dev/null | cut -d= -f2- | tr -d '\"')\"\n [[ -z \"${chat}\" ]] && chat=\"$(grep -m1 -E '^TELEGRAM_(OWNER|APPROVAL)_CHAT_ID=' \"$f\" 2>/dev/null | cut -d= -f2- | tr -d '\"')\"\n done\n fi\n if [[ -z \"${tok}\" || -z \"${chat}\" ]]; then\n log \"WARN: telegram creds unresolved — human-alert suppressed: ${msg}\"\n return 0\n fi\n curl -sS --max-time 20 -X POST \"https://api.telegram.org/bot${tok}/sendMessage\" \\\n -d \"chat_id=${chat}\" -d \"text=${msg}\" >/dev/null 2>&1 || true\n}\n\nlog \"world-scan starting (week=${WEEK_TAG}, out=${OUTPUT_FILE})\"\n\n# --- idempotence: one scan per week ---\nif [ -s \"$OUTPUT_FILE\" ]; then\n log \"skip: ${OUTPUT_FILE} already exists ($(wc -l < \"$OUTPUT_FILE\") lines). Delete to re-run.\"\n exit 0\nfi\n\n# --- worktree-isolation guard (same discipline as scar-replay-run.sh): never\n# run from inside the shared deploy worktree ---\ncase \"$(pwd -P)/\" in\n \"${REPO_ROOT}/\"*) log \"REFUSE: cwd inside shared deploy worktree; aborting.\"; exit 0 ;;\nesac\n\n# --- secrets: DEEPSEEK_API_KEY (with vault drift fallback) + telegram ---\nDS_KEY=\"${DEEPSEEK_API_KEY:-}\"\nif [ -z \"$DS_KEY\" ]; then\n for f in \"${HOME}/.nuzantara-secrets.env\" \"${HOME}/.openclaw/workspace/.env.master\"; do\n [ -f \"$f\" ] || continue\n line=$(grep -m1 -E '^DEEPSEEK_API_KEY=' \"$f\" 2>/dev/null || true)\n [ -n \"$line\" ] && { DS_KEY=\"${line#DEEPSEEK_API_KEY=}\"; DS_KEY=\"${DS_KEY%\\\"}\"; DS_KEY=\"${DS_KEY#\\\"}\"; break; }\n done\nfi\nif [ -z \"$DS_KEY\" ]; then\n log \"FATAL: DEEPSEEK_API_KEY not found in any vault — cannot translate. Aborting.\"\n exit 2\nfi\nexport DEEPSEEK_API_KEY=\"$DS_KEY\"\n\nmkdir -p \"$PROPOSED_DIR\"\n\n# --- Step 1: INGEST + EXTRACT via Claude Opus agent (OAuth-only, web search) ---\n# Reuse of the wr2-external-bench invocation shape. The agent does the web\n# research and emits a strict JSON array of failure patterns to PATTERNS_JSON.\nINGEST_PROMPT=\"You are world-scan, the evolver's external research scout.\n\nResearch the LAST ~30 days of public best-practices and post-mortems on:\n - SRE / reliability engineering (toil, retries, idempotency, locking, queues)\n - chaos engineering & fault injection\n - autonomous-agent / LLM-agent failure modes (loops, drift, tool misuse, state)\n - CI/CD & git-worktree / deploy hazards\nUse web search. Prefer concrete engineering write-ups (incident reports, SRE\nbooks/blogs, postmortems), NOT listicles.\n\nExtract 6-12 DISTINCT failure patterns relevant to a self-improving ops agent\nthat runs local git worktrees, LaunchAgent cron, shell scripts, Postgres.\n\nWrite ONLY a strict JSON array to ${PATTERNS_JSON}, each item:\n {\\\"title\\\": \\\"...\\\", \\\"text\\\": \\\"2-4 sentence description of the failure mode and why it bites\\\", \\\"source\\\": \\\"url or outlet\\\"}\nNo prose around the JSON. Reject vague/cultural advice — only concrete, testable failure mechanics.\"\n\nCLAUDE_BIN=\"${HOME}/.local/bin/claude\"; [ -x \"$CLAUDE_BIN\" ] || CLAUDE_BIN=\"/opt/homebrew/bin/claude\"\n\nlog \"step1: ingest+extract via claude opus (web search)\"\ntimeout 1800 \"$CLAUDE_BIN\" -p \\\n --model claude-opus-4-8 \\\n --permission-mode bypassPermissions \\\n \"$INGEST_PROMPT\" >> \"$LOG\" 2>> \"$ERR\" || log \"WARN: ingest agent exit=$?\"\n\nif [ ! -s \"$PATTERNS_JSON\" ]; then\n log \"FATAL: no patterns JSON produced at ${PATTERNS_JSON}. Aborting.\"\n # Telegram: this needs a human (ingest produced nothing).\n telegram_alert \"⚠️ world-scan ${WEEK_TAG}: ingest produced no patterns. Check ${ERR}.\"\n exit 3\nfi\nlog \"step1 done: $(wc -c < \"$PATTERNS_JSON\") bytes of patterns\"\n\n# --- Step 2+3: TRANSLATE each pattern + STAGE drafts ---\nlog \"step2: translate patterns -> draft probes (DeepSeek + deterministic gate)\"\nPYTHONPATH=\"${HARNESS_DIR}\" python3 - \"$PATTERNS_JSON\" \"$OUTPUT_FILE\" \"$WEEK_TAG\" <<'PYEOF' >> \"$LOG\" 2>> \"$ERR\"\nimport json, sys, os, datetime\nsys.path.insert(0, os.environ[\"PYTHONPATH\"])\nimport world_scan_translate as wt\n\npatterns_path, out_path, week = sys.argv[1], sys.argv[2], sys.argv[3]\nkey = os.environ[\"DEEPSEEK_API_KEY\"]\npatterns = json.load(open(patterns_path))\nif not isinstance(patterns, list):\n print(\"patterns JSON is not a list — abort\"); sys.exit(4)\n\ndrafts = []\nfor p in patterns:\n title = (p.get(\"title\") or \"untitled\").strip()\n text = (p.get(\"text\") or \"\") + \"\\nSource: \" + (p.get(\"source\") or \"\")\n d = wt.translate_pattern(key, title, text)\n d.source_refs = p.get(\"source\") or title\n drafts.append(d)\n\nadopt = [d for d in drafts if d.category == \"ADOPT\"]\nobserve = [d for d in drafts if d.category == \"OBSERVE\"]\nreject = [d for d in drafts if d.category == \"REJECT\"]\n\nheader = (\n f\"# World-Scan draft probes — {week}\\n\\n\"\n f\"> Auto-generated by world-scan (reuse-first fork of wr2-external-bench). \"\n f\"These are DRAFT replay-probes proposed from external failure patterns. \"\n f\"**Nothing here is live.** A human promotes an ADOPT draft into \"\n f\"`agent-library/scar_replay/scar_probes.py` by hand (fixture + assertion as \"\n f\"code) and commits it. Never auto-merged (Law 5).\\n\\n\"\n f\"**Summary:** {len(adopt)} ADOPT · {len(observe)} OBSERVE · {len(reject)} REJECT \"\n f\"(of {len(drafts)} patterns scanned).\\n\\n---\\n\\n\"\n)\nbody = \"\".join(wt.render_draft_md(d) for d in (adopt + observe + reject))\nopen(out_path, \"w\").write(header + body)\nprint(f\"WORLD_SCAN_SUMMARY adopt={len(adopt)} observe={len(observe)} reject={len(reject)} total={len(drafts)}\")\nPYEOF\n\nif [ ! -s \"$OUTPUT_FILE\" ]; then\n log \"FATAL: translation produced no output file. Check ${ERR}.\"\n telegram_alert \"⚠️ world-scan ${WEEK_TAG}: translation failed. Check ${ERR}.\"\n exit 5\nfi\n\nSUMMARY=$(grep -h \"WORLD_SCAN_SUMMARY\" \"$LOG\" | tail -1 || echo \"summary unavailable\")\nlog \"step3 done: ${OUTPUT_FILE} ($(wc -l < \"$OUTPUT_FILE\") lines) — ${SUMMARY}\"\n\n# --- Step 4: notify (human reviews; never auto-merge) ---\ntelegram_alert \"🌐 world-scan ${WEEK_TAG} done. ${SUMMARY}. Draft probes staged at research/operations/_proposed/${WEEK_TAG}-world-scan-probes.md — review & promote ADOPT drafts by hand.\"\nlog \"DONE world-scan ${WEEK_TAG}\"\nexit 0\n"}, "c6c3142a1f0bb3b195089705d9b3a88a5bce1896": {"t": 1785758297.456125, "n": 8296, "h": "066da63e4a87cabb", "c": "#!/bin/bash\n# world-scan-run.sh — weekly external failure-pattern scan for the evolver.\n#\n# Reuse-first (2026-06-04): forked from ~/scripts/wr2-external-bench-run.sh.\n# ~80% reused (multi-LLM ingest+extract via a Claude agent, DeepSeek translate\n# via world_scan_translate.py, devils-advocate-style gate built into the\n# translator's deterministic grade, _proposed/ staging, Telegram). The only NEW\n# code is world_scan_translate.py (pattern -> draft executable probe).\n#\n# Pipeline:\n# 1. INGEST+EXTRACT (Claude Opus agent w/ web search): scan SRE/security/\n# agent-failure sources -> JSON list of failure patterns.\n# 2. TRANSLATE (world_scan_translate.py + DeepSeek): each pattern -> draft probe\n# with a DETERMINISTIC executability gate (ADOPT/OBSERVE/REJECT).\n# 3. STAGE: write drafts to research/operations/_proposed/<date>-world-scan.md.\n# 4. NOTIFY: Telegram summary to Antonello. NEVER auto-merge; human promotes\n# an ADOPT draft into scar_probes.py by hand.\n#\n# Cron: weekly (1st-of-week guard inside). Schedule via LaunchAgent.\n# Cost: ~$0.05/week (Gemini/Claude OAuth + DeepSeek translate calls).\n\nset -euo pipefail\n\nLOGDIR=\"${HOME}/logs\"; mkdir -p \"$LOGDIR\"\nLOG=\"$LOGDIR/world-scan.log\"\nERR=\"$LOGDIR/world-scan.err.log\"\n\nHARNESS_DIR=\"${SCAR_REPLAY_DIR:-${HOME}/Desktop/nuzantara-deploy/agent-library/scar_replay}\"\nREPO_ROOT=\"${WORLD_SCAN_REPO_ROOT:-${HOME}/Desktop/nuzantara-deploy}\"\nWEEK_TAG=\"$(date +%Y-W%V)\"\nPROPOSED_DIR=\"${REPO_ROOT}/research/operations/_proposed\"\nOUTPUT_FILE=\"${PROPOSED_DIR}/${WEEK_TAG}-world-scan-probes.md\"\nPATTERNS_JSON=\"/tmp/world-scan-patterns-${WEEK_TAG}.json\"\n\nlog() { echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*\" >> \"$LOG\"; }\n\n# telegram_alert: reused verbatim from scar-replay-run.sh (#1090). Resolves token\n# + chat id from sanctioned vaults; tolerates OWNER vs APPROVAL chat-id naming\n# drift; suppresses silently if creds unresolved (Law 4 — never block on outage).\ntelegram_alert() {\n local msg=\"$1\"\n local tok=\"${TELEGRAM_BOT_TOKEN:-}\"\n local chat=\"${TELEGRAM_OWNER_CHAT_ID:-${TELEGRAM_APPROVAL_CHAT_ID:-}}\"\n if [[ -z \"${tok}\" || -z \"${chat}\" ]]; then\n for f in \"${HOME}/.nuzantara-secrets.env\" \"${HOME}/.openclaw/workspace/.env.master\"; do\n [[ -f \"$f\" ]] || continue\n [[ -z \"${tok}\" ]] && tok=\"$(grep -m1 -E '^TELEGRAM_BOT_TOKEN=' \"$f\" 2>/dev/null | cut -d= -f2- | tr -d '\"')\"\n [[ -z \"${chat}\" ]] && chat=\"$(grep -m1 -E '^TELEGRAM_(OWNER|APPROVAL)_CHAT_ID=' \"$f\" 2>/dev/null | cut -d= -f2- | tr -d '\"')\"\n done\n fi\n if [[ -z \"${tok}\" || -z \"${chat}\" ]]; then\n log \"WARN: telegram creds unresolved — human-alert suppressed: ${msg}\"\n return 0\n fi\n curl -sS --max-time 20 -X POST \"https://api.telegram.org/bot${tok}/sendMessage\" \\\n -d \"chat_id=${chat}\" -d \"text=${msg}\" >/dev/null 2>&1 || true\n}\n\nlog \"world-scan starting (week=${WEEK_TAG}, out=${OUTPUT_FILE})\"\n\n# --- idempotence: one scan per week ---\nif [ -s \"$OUTPUT_FILE\" ]; then\n log \"skip: ${OUTPUT_FILE} already exists ($(wc -l < \"$OUTPUT_FILE\") lines). Delete to re-run.\"\n exit 0\nfi\n\n# --- worktree-isolation guard (same discipline as scar-replay-run.sh): never\n# run from inside the shared deploy worktree ---\ncase \"$(pwd -P)/\" in\n \"${REPO_ROOT}/\"*) log \"REFUSE: cwd inside shared deploy worktree; aborting.\"; exit 0 ;;\nesac\n\n# --- secrets: DEEPSEEK_API_KEY (with vault drift fallback) + telegram ---\nDS_KEY=\"${DEEPSEEK_API_KEY:-}\"\nif [ -z \"$DS_KEY\" ]; then\n for f in \"${HOME}/.nuzantara-secrets.env\" \"${HOME}/.openclaw/workspace/.env.master\"; do\n [ -f \"$f\" ] || continue\n line=$(grep -m1 -E '^DEEPSEEK_API_KEY=' \"$f\" 2>/dev/null || true)\n [ -n \"$line\" ] && { DS_KEY=\"${line#DEEPSEEK_API_KEY=}\"; DS_KEY=\"${DS_KEY%\\\"}\"; DS_KEY=\"${DS_KEY#\\\"}\"; break; }\n done\nfi\nif [ -z \"$DS_KEY\" ]; then\n log \"FATAL: DEEPSEEK_API_KEY not found in any vault — cannot translate. Aborting.\"\n exit 2\nfi\nexport DEEPSEEK_API_KEY=\"$DS_KEY\"\n\nmkdir -p \"$PROPOSED_DIR\"\n\n# --- Step 1: INGEST + EXTRACT via Claude Opus agent (OAuth-only, web search) ---\n# Reuse of the wr2-external-bench invocation shape. The agent does the web\n# research and emits a strict JSON array of failure patterns to PATTERNS_JSON.\nINGEST_PROMPT=\"You are world-scan, the evolver's external research scout.\n\nResearch the LAST ~30 days of public best-practices and post-mortems on:\n - SRE / reliability engineering (toil, retries, idempotency, locking, queues)\n - chaos engineering & fault injection\n - autonomous-agent / LLM-agent failure modes (loops, drift, tool misuse, state)\n - CI/CD & git-worktree / deploy hazards\nUse web search. Prefer concrete engineering write-ups (incident reports, SRE\nbooks/blogs, postmortems), NOT listicles.\n\nExtract 6-12 DISTINCT failure patterns relevant to a self-improving ops agent\nthat runs local git worktrees, LaunchAgent cron, shell scripts, Postgres.\n\nWrite ONLY a strict JSON array to ${PATTERNS_JSON}, each item:\n {\\\"title\\\": \\\"...\\\", \\\"text\\\": \\\"2-4 sentence description of the failure mode and why it bites\\\", \\\"source\\\": \\\"url or outlet\\\"}\nNo prose around the JSON. Reject vague/cultural advice — only concrete, testable failure mechanics.\"\n\nCLAUDE_BIN=\"${HOME}/.local/bin/claude\"; [ -x \"$CLAUDE_BIN\" ] || CLAUDE_BIN=\"/opt/homebrew/bin/claude\"\n\nlog \"step1: ingest+extract via claude opus (web search)\"\ntimeout 1800 \"$CLAUDE_BIN\" -p \\\n --model claude-opus-4-8 \\\n --permission-mode bypassPermissions \\\n \"$INGEST_PROMPT\" >> \"$LOG\" 2>> \"$ERR\" || log \"WARN: ingest agent exit=$?\"\n\nif [ ! -s \"$PATTERNS_JSON\" ]; then\n log \"FATAL: no patterns JSON produced at ${PATTERNS_JSON}. Aborting.\"\n # Telegram: this needs a human (ingest produced nothing).\n telegram_alert \"⚠️ world-scan ${WEEK_TAG}: ingest produced no patterns. Check ${ERR}.\"\n exit 3\nfi\nlog \"step1 done: $(wc -c < \"$PATTERNS_JSON\") bytes of patterns\"\n\n# --- Step 2+3: TRANSLATE each pattern + STAGE drafts ---\nlog \"step2: translate patterns -> draft probes (DeepSeek + deterministic gate)\"\nPYTHONPATH=\"${HARNESS_DIR}\" python3 - \"$PATTERNS_JSON\" \"$OUTPUT_FILE\" \"$WEEK_TAG\" <<'PYEOF' >> \"$LOG\" 2>> \"$ERR\"\nimport json, sys, os, datetime\nsys.path.insert(0, os.environ[\"PYTHONPATH\"])\nimport world_scan_translate as wt\n\npatterns_path, out_path, week = sys.argv[1], sys.argv[2], sys.argv[3]\nkey = os.environ[\"DEEPSEEK_API_KEY\"]\npatterns = json.load(open(patterns_path))\nif not isinstance(patterns, list):\n print(\"patterns JSON is not a list — abort\"); sys.exit(4)\n\ndrafts = []\nfor p in patterns:\n title = (p.get(\"title\") or \"untitled\").strip()\n text = (p.get(\"text\") or \"\") + \"\\nSource: \" + (p.get(\"source\") or \"\")\n d = wt.translate_pattern(key, title, text)\n d.source_refs = p.get(\"source\") or title\n drafts.append(d)\n\nadopt = [d for d in drafts if d.category == \"ADOPT\"]\nobserve = [d for d in drafts if d.category == \"OBSERVE\"]\nreject = [d for d in drafts if d.category == \"REJECT\"]\n\nheader = (\n f\"# World-Scan draft probes — {week}\\n\\n\"\n f\"> Auto-generated by world-scan (reuse-first fork of wr2-external-bench). \"\n f\"These are DRAFT replay-probes proposed from external failure patterns. \"\n f\"**Nothing here is live.** A human promotes an ADOPT draft into \"\n f\"`agent-library/scar_replay/scar_probes.py` by hand (fixture + assertion as \"\n f\"code) and commits it. Never auto-merged (Law 5).\\n\\n\"\n f\"**Summary:** {len(adopt)} ADOPT · {len(observe)} OBSERVE · {len(reject)} REJECT \"\n f\"(of {len(drafts)} patterns scanned).\\n\\n---\\n\\n\"\n)\nbody = \"\".join(wt.render_draft_md(d) for d in (adopt + observe + reject))\nopen(out_path, \"w\").write(header + body)\nprint(f\"WORLD_SCAN_SUMMARY adopt={len(adopt)} observe={len(observe)} reject={len(reject)} total={len(drafts)}\")\nPYEOF\n\nif [ ! -s \"$OUTPUT_FILE\" ]; then\n log \"FATAL: translation produced no output file. Check ${ERR}.\"\n telegram_alert \"⚠️ world-scan ${WEEK_TAG}: translation failed. Check ${ERR}.\"\n exit 5\nfi\n\nSUMMARY=$(grep -h \"WORLD_SCAN_SUMMARY\" \"$LOG\" | tail -1 || echo \"summary unavailable\")\nlog \"step3 done: ${OUTPUT_FILE} ($(wc -l < \"$OUTPUT_FILE\") lines) — ${SUMMARY}\"\n\n# --- Step 4: notify (human reviews; never auto-merge) ---\ntelegram_alert \"🌐 world-scan ${WEEK_TAG} done. ${SUMMARY}. Draft probes staged at research/operations/_proposed/${WEEK_TAG}-world-scan-probes.md — review & promote ADOPT drafts by hand.\"\nlog \"DONE world-scan ${WEEK_TAG}\"\nexit 0\n"}}, "docs/specs/arsenal-probe-v1.md": {"9e8bb6055c42e72817fc7b01bc5035a2a7b7bf41": {"t": 1785746399.636789, "n": 8306, "h": "75d3df861bc8453a", "c": "# Arsenal Probe v1 — spec (DESIGN artifact, modus stage 2)\n\nDate: 2026-07-06 · Author: Fable 5 (interactive) · Implementer: Sonnet 5 (worktree ops-arsenal-probe)\nMandate: Zero 2026-07-06 \"sonda pesantemente\" — the quota-cascade can silently degrade to 2-deep\n(Codex 401 silent, agy keychain-bound, GLM 529/401, DeepSeek 402). Recommended since 2026-05-24,\nnever armed. This tool makes every AI seat's liveness EMPIRICAL, per-machine, per-context.\n\n## What it is\n\n`scripts/arsenal_probe.py` — a standalone, signal-only prober (never mutates anything outside\n`~/.organism/`). One run = live-probe every AI seat reachable from THIS machine, classify each\ninto an honest taxonomy, write a JSON report + heartbeat sidecar, detect transitions vs the\nprevious run. Consumed by: healer wrapper (Mini, 4h), proprioception (freshness + verdict reader),\nhumans (`--table`).\n\n## Seats & probe commands (each: subprocess, per-seat timeout, thread-parallel)\n\n| seat | probe | LIVE signal |\n|---|---|---|\n| claude | `$ARSENAL_CLAUDE_BIN -p \"Reply with exactly: PONG\" --model claude-sonnet-5` (default bin `/opt/homebrew/bin/claude`; strip `ANTHROPIC_API_KEY` from env, pass through `CLAUDE_CODE_OAUTH_TOKEN` if set) | `PONG` in stdout |\n| glm | token = `security find-generic-password -s glm-coding-plan-token -w` (NEVER logged); direct `curl` POST `https://api.z.ai/api/anthropic/v1/messages`, model `glm-5.2`, max_tokens 8, anthropic-version 2023-06-01 | HTTP 200 + `\"model\"` in body |\n| agy | `agy -p \"Reply with exactly: PONG\"` (which-resolve; also try `~/.local/bin/agy`) | `PONG` in stdout |\n| codex | `codex exec --sandbox read-only --skip-git-repo-check \"Reply with exactly: PONG\"` with stdin=DEVNULL (it blocks on open stdin) | `PONG` in stdout |\n| deepseek | key = parse `DEEPSEEK_API_KEY=` from `~/.openclaw/workspace/.env.master` (read in-python, value NEVER logged); `curl` POST `https://api.deepseek.com/chat/completions` model `deepseek-v4-flash`, max_tokens 1 | HTTP 200 |\n| ollama | `ollama list` → presence of `qwen3.5`; with `--live-gen` also 1-token `ollama run qwen3.5:9b` | model listed (or gen output) |\n| nlm | `nlm list notebooks` (which-resolve) | stdout parses as JSON (list or dict) |\n\nTimeouts (defaults, per-seat override via `--timeout SEC` global multiplier): claude 120s,\nglm 45s, agy 120s, codex 180s, deepseek 45s, ollama 30s (live-gen 120s), nlm 60s.\n\n## Status taxonomy (the heart — classify by OUTPUT CONTENT, never exit code alone; scar #2)\n\n- `LIVE` — the live signal observed.\n- `AUTH_DEAD` — output matches `401|Authentication Failed|token_revoked|refresh_token_reused|OAuth token|authentication failed` (codex/glm/claude/nlm auth class). For agy: only when NOT in an ssh context.\n- `CONTEXT_AUTH` — agy-style GUI-keychain failure while `SSH_CONNECTION`/`SSH_TTY` env present or no GUI session: the seat is dead IN THIS CONTEXT, possibly alive in GUI. Distinct because the cure differs (context, not credential).\n- `QUOTA_DEAD` — `out of extra usage|usage limit|quota|429|rate.limit|exhausted`.\n- `BALANCE_DEAD` — HTTP 402 / `Insufficient Balance` (deepseek class).\n- `MODEL_ERR` — `1211|Unknown Model` (glm class — config drift, e.g. the fable-5[1m] leak).\n- `SHED` — HTTP 529 / `overloaded` (provider-side transient load-shedding).\n- `TIMEOUT` — probe hit its per-seat timeout.\n- `CRED_UNAVAILABLE` — credential source absent/locked on this host (keychain locked → `security` exit 36/25300-class or empty in non-interactive; env.master missing; token file absent). NOT a seat death — a host limitation. Never strict-fails.\n- `NOT_INSTALLED` — binary not found on PATH (nor known fallback paths). Never strict-fails.\n- `UNKNOWN_ERR` — none of the above matched; evidence tail retained.\n\n`healthy` bool = status == LIVE. `context_limited` = status in {CONTEXT_AUTH, CRED_UNAVAILABLE, NOT_INSTALLED}.\nSTRICT-FAIL set (persistent + fixable): {AUTH_DEAD, BALANCE_DEAD, MODEL_ERR, UNKNOWN_ERR}.\n(QUOTA_DEAD/SHED/TIMEOUT are alarm-worthy transitions but transient — never exit-1.)\n\n## Machine awareness\n\n`machine_label()`: hostname → `m5` (Air-M5) / `pro` (Nuzantara) / `mini` (Mini-Pro2) / raw-lowercase.\nDefault seat selection = all 7; `--seats claude,glm,...` filters. REQUIRED map (used by `--strict`):\n`mini: [claude, glm, codex, ollama]` · `pro: [claude, codex, deepseek, ollama, nlm]` ·\n`m5: [claude, glm, agy, codex]` — a required seat in the STRICT-FAIL set → exit 1.\nNon-required seats always probed and reported (unless filtered), just never fail the run.\n\n## Outputs\n\n1. Report `~/.organism/arsenal/last.json` (atomic write via tempfile+rename; keep previous as\n `prev.json` before overwrite):\n```json\n{\"schema\": 1, \"machine\": \"mini\", \"ts\": \"2026-07-06T12:00:00Z\",\n \"context\": {\"ssh\": true, \"interactive\": false},\n \"seats\": [{\"seat\": \"glm\", \"status\": \"LIVE\", \"healthy\": true, \"latency_ms\": 1240,\n \"evidence\": \"HTTP 200 model glm-5.2\", \"required\": true}],\n \"transitions\": [{\"seat\": \"codex\", \"from\": \"LIVE\", \"to\": \"AUTH_DEAD\"}],\n \"summary\": {\"live\": 5, \"dead_strict\": 1, \"context_limited\": 1, \"transient\": 0}}\n```\n2. Heartbeat `~/.organism/last_seen/<machine>.arsenal_probe.json` — same shape as healer's:\n `{\"organ\": \"<machine>.arsenal_probe\", \"status\": \"ok|degraded\", \"note\": \"<summary line>\", \"ts\": ...}`\n (`degraded` iff any strict-fail among required seats).\n3. stdout: human table by default; `--json` full report; `--quiet` one summary line.\n\n## Flags\n\n`--seats CSV` · `--json` · `--table` (default) · `--quiet` · `--strict` · `--timeout MULT`\n(float multiplier on all per-seat timeouts) · `--live-gen` (ollama real generate) ·\n`--read-last` (NO probing: re-emit last.json as `{\"findings\": [seats not in ok-set]}` for the\nproprioception wrap consumer; missing file → `{\"findings\": [{\"seat\": \"(all)\", \"status\": \"NEVER_RAN\"}]}`) ·\n`--selftest` (see below).\n\n## Redaction (scar #4 — non-negotiable)\n\nEvidence tails (≤160 chars) pass through `scrub()`: replace `Bearer\\s+\\S+`, `sk-[A-Za-z0-9_-]{8,}`,\nany 24+ char alnum/`._-` token, and the literal values of any env var whose NAME matches\n`(TOKEN|KEY|PASSWORD|SECRET)` that the probe itself loaded, with `<REDACTED>`. Credential values\nlive only in locals, never in the report, never in exceptions (wrap curl calls so the\nAuthorization header never appears in error strings). `security`/env.master reads must not echo.\n\n## Selftest (W84 blind-scan guard)\n\n`--selftest`: (a) classifier table — canned output samples per status (the real strings above:\nz.ai 1211 body, 529 body, codex token_revoked line, agy auth-failed line, deepseek 402, quota\nstrings) each classify correctly; (b) scrub() removes a planted fake token; (c) blind-scan guard:\na run that probed 0 seats must exit 2, never \"clean\"; (d) `--read-last` on a fixture file. Exit 0\nonly if all pass, print `SELFTEST OK — N checks`.\n\n## Tests — `scripts/tests/test_arsenal_probe.py` (pytest, NO live network/LLM calls)\n\nMonkeypatch subprocess/HTTP layers. Guilt AND innocence per classifier (e.g. `PONG` → LIVE never\nAUTH_DEAD; `1211` → MODEL_ERR never SHED; agy auth-fail + SSH_CONNECTION set → CONTEXT_AUTH,\nwithout ssh env → AUTH_DEAD). Transitions computed vs prev report. Strict exit semantics: required\nAUTH_DEAD → 1; CRED_UNAVAILABLE → 0. Redaction: fake `Bearer abc...` and a 40-char token never\nappear in report JSON. Atomic write leaves prev.json. `--read-last` fixtures (ok-set filtering,\nNEVER_RAN). Blind-scan exit 2. Aim ~20-30 focused tests. Style: mirror existing\n`scripts/tests/test_pending_arms_report.py` conventions (tmp_path, capsys).\n\n## Explicitly OUT of scope for the implementer (Fable does these after, funnel-in)\n\n- Edits to `scripts/proprioception.py` (guardian_freshness item + wrap registry entry)\n- Edits to `infra/healer/healer-run.sh` (receptor 4: run probe + transitions→ACTIONABLE + Telegram line)\n- `.github/workflows/immune-enforcement.yml` test wiring\n- `docs/runbooks/arsenal-probe.md`\n- PENDING-ARMS arming lines\n\n## Style contract\n\nPython 3.11 stdlib-only (subprocess, json, concurrent.futures, urllib.request for HTTP — no\nrequests dep), full type hints, logger-style stderr prints OK for a CLI tool, module docstring\nwith the one-line mission + scar references (#2 Esiste≠Armato, #4 secrets, W84 blind-scan).\nMatch the voice of `scripts/proprioception.py` (concise comments explaining WHY, not what).\n"}, "4e43a923b76601fcbae6810d61f0a6cf1fbc9bf5": {"t": 1785758296.2479012, "n": 8306, "h": "75d3df861bc8453a", "c": "# Arsenal Probe v1 — spec (DESIGN artifact, modus stage 2)\n\nDate: 2026-07-06 · Author: Fable 5 (interactive) · Implementer: Sonnet 5 (worktree ops-arsenal-probe)\nMandate: Zero 2026-07-06 \"sonda pesantemente\" — the quota-cascade can silently degrade to 2-deep\n(Codex 401 silent, agy keychain-bound, GLM 529/401, DeepSeek 402). Recommended since 2026-05-24,\nnever armed. This tool makes every AI seat's liveness EMPIRICAL, per-machine, per-context.\n\n## What it is\n\n`scripts/arsenal_probe.py` — a standalone, signal-only prober (never mutates anything outside\n`~/.organism/`). One run = live-probe every AI seat reachable from THIS machine, classify each\ninto an honest taxonomy, write a JSON report + heartbeat sidecar, detect transitions vs the\nprevious run. Consumed by: healer wrapper (Mini, 4h), proprioception (freshness + verdict reader),\nhumans (`--table`).\n\n## Seats & probe commands (each: subprocess, per-seat timeout, thread-parallel)\n\n| seat | probe | LIVE signal |\n|---|---|---|\n| claude | `$ARSENAL_CLAUDE_BIN -p \"Reply with exactly: PONG\" --model claude-sonnet-5` (default bin `/opt/homebrew/bin/claude`; strip `ANTHROPIC_API_KEY` from env, pass through `CLAUDE_CODE_OAUTH_TOKEN` if set) | `PONG` in stdout |\n| glm | token = `security find-generic-password -s glm-coding-plan-token -w` (NEVER logged); direct `curl` POST `https://api.z.ai/api/anthropic/v1/messages`, model `glm-5.2`, max_tokens 8, anthropic-version 2023-06-01 | HTTP 200 + `\"model\"` in body |\n| agy | `agy -p \"Reply with exactly: PONG\"` (which-resolve; also try `~/.local/bin/agy`) | `PONG` in stdout |\n| codex | `codex exec --sandbox read-only --skip-git-repo-check \"Reply with exactly: PONG\"` with stdin=DEVNULL (it blocks on open stdin) | `PONG` in stdout |\n| deepseek | key = parse `DEEPSEEK_API_KEY=` from `~/.openclaw/workspace/.env.master` (read in-python, value NEVER logged); `curl` POST `https://api.deepseek.com/chat/completions` model `deepseek-v4-flash`, max_tokens 1 | HTTP 200 |\n| ollama | `ollama list` → presence of `qwen3.5`; with `--live-gen` also 1-token `ollama run qwen3.5:9b` | model listed (or gen output) |\n| nlm | `nlm list notebooks` (which-resolve) | stdout parses as JSON (list or dict) |\n\nTimeouts (defaults, per-seat override via `--timeout SEC` global multiplier): claude 120s,\nglm 45s, agy 120s, codex 180s, deepseek 45s, ollama 30s (live-gen 120s), nlm 60s.\n\n## Status taxonomy (the heart — classify by OUTPUT CONTENT, never exit code alone; scar #2)\n\n- `LIVE` — the live signal observed.\n- `AUTH_DEAD` — output matches `401|Authentication Failed|token_revoked|refresh_token_reused|OAuth token|authentication failed` (codex/glm/claude/nlm auth class). For agy: only when NOT in an ssh context.\n- `CONTEXT_AUTH` — agy-style GUI-keychain failure while `SSH_CONNECTION`/`SSH_TTY` env present or no GUI session: the seat is dead IN THIS CONTEXT, possibly alive in GUI. Distinct because the cure differs (context, not credential).\n- `QUOTA_DEAD` — `out of extra usage|usage limit|quota|429|rate.limit|exhausted`.\n- `BALANCE_DEAD` — HTTP 402 / `Insufficient Balance` (deepseek class).\n- `MODEL_ERR` — `1211|Unknown Model` (glm class — config drift, e.g. the fable-5[1m] leak).\n- `SHED` — HTTP 529 / `overloaded` (provider-side transient load-shedding).\n- `TIMEOUT` — probe hit its per-seat timeout.\n- `CRED_UNAVAILABLE` — credential source absent/locked on this host (keychain locked → `security` exit 36/25300-class or empty in non-interactive; env.master missing; token file absent). NOT a seat death — a host limitation. Never strict-fails.\n- `NOT_INSTALLED` — binary not found on PATH (nor known fallback paths). Never strict-fails.\n- `UNKNOWN_ERR` — none of the above matched; evidence tail retained.\n\n`healthy` bool = status == LIVE. `context_limited` = status in {CONTEXT_AUTH, CRED_UNAVAILABLE, NOT_INSTALLED}.\nSTRICT-FAIL set (persistent + fixable): {AUTH_DEAD, BALANCE_DEAD, MODEL_ERR, UNKNOWN_ERR}.\n(QUOTA_DEAD/SHED/TIMEOUT are alarm-worthy transitions but transient — never exit-1.)\n\n## Machine awareness\n\n`machine_label()`: hostname → `m5` (Air-M5) / `pro` (Nuzantara) / `mini` (Mini-Pro2) / raw-lowercase.\nDefault seat selection = all 7; `--seats claude,glm,...` filters. REQUIRED map (used by `--strict`):\n`mini: [claude, glm, codex, ollama]` · `pro: [claude, codex, deepseek, ollama, nlm]` ·\n`m5: [claude, glm, agy, codex]` — a required seat in the STRICT-FAIL set → exit 1.\nNon-required seats always probed and reported (unless filtered), just never fail the run.\n\n## Outputs\n\n1. Report `~/.organism/arsenal/last.json` (atomic write via tempfile+rename; keep previous as\n `prev.json` before overwrite):\n```json\n{\"schema\": 1, \"machine\": \"mini\", \"ts\": \"2026-07-06T12:00:00Z\",\n \"context\": {\"ssh\": true, \"interactive\": false},\n \"seats\": [{\"seat\": \"glm\", \"status\": \"LIVE\", \"healthy\": true, \"latency_ms\": 1240,\n \"evidence\": \"HTTP 200 model glm-5.2\", \"required\": true}],\n \"transitions\": [{\"seat\": \"codex\", \"from\": \"LIVE\", \"to\": \"AUTH_DEAD\"}],\n \"summary\": {\"live\": 5, \"dead_strict\": 1, \"context_limited\": 1, \"transient\": 0}}\n```\n2. Heartbeat `~/.organism/last_seen/<machine>.arsenal_probe.json` — same shape as healer's:\n `{\"organ\": \"<machine>.arsenal_probe\", \"status\": \"ok|degraded\", \"note\": \"<summary line>\", \"ts\": ...}`\n (`degraded` iff any strict-fail among required seats).\n3. stdout: human table by default; `--json` full report; `--quiet` one summary line.\n\n## Flags\n\n`--seats CSV` · `--json` · `--table` (default) · `--quiet` · `--strict` · `--timeout MULT`\n(float multiplier on all per-seat timeouts) · `--live-gen` (ollama real generate) ·\n`--read-last` (NO probing: re-emit last.json as `{\"findings\": [seats not in ok-set]}` for the\nproprioception wrap consumer; missing file → `{\"findings\": [{\"seat\": \"(all)\", \"status\": \"NEVER_RAN\"}]}`) ·\n`--selftest` (see below).\n\n## Redaction (scar #4 — non-negotiable)\n\nEvidence tails (≤160 chars) pass through `scrub()`: replace `Bearer\\s+\\S+`, `sk-[A-Za-z0-9_-]{8,}`,\nany 24+ char alnum/`._-` token, and the literal values of any env var whose NAME matches\n`(TOKEN|KEY|PASSWORD|SECRET)` that the probe itself loaded, with `<REDACTED>`. Credential values\nlive only in locals, never in the report, never in exceptions (wrap curl calls so the\nAuthorization header never appears in error strings). `security`/env.master reads must not echo.\n\n## Selftest (W84 blind-scan guard)\n\n`--selftest`: (a) classifier table — canned output samples per status (the real strings above:\nz.ai 1211 body, 529 body, codex token_revoked line, agy auth-failed line, deepseek 402, quota\nstrings) each classify correctly; (b) scrub() removes a planted fake token; (c) blind-scan guard:\na run that probed 0 seats must exit 2, never \"clean\"; (d) `--read-last` on a fixture file. Exit 0\nonly if all pass, print `SELFTEST OK — N checks`.\n\n## Tests — `scripts/tests/test_arsenal_probe.py` (pytest, NO live network/LLM calls)\n\nMonkeypatch subprocess/HTTP layers. Guilt AND innocence per classifier (e.g. `PONG` → LIVE never\nAUTH_DEAD; `1211` → MODEL_ERR never SHED; agy auth-fail + SSH_CONNECTION set → CONTEXT_AUTH,\nwithout ssh env → AUTH_DEAD). Transitions computed vs prev report. Strict exit semantics: required\nAUTH_DEAD → 1; CRED_UNAVAILABLE → 0. Redaction: fake `Bearer abc...` and a 40-char token never\nappear in report JSON. Atomic write leaves prev.json. `--read-last` fixtures (ok-set filtering,\nNEVER_RAN). Blind-scan exit 2. Aim ~20-30 focused tests. Style: mirror existing\n`scripts/tests/test_pending_arms_report.py` conventions (tmp_path, capsys).\n\n## Explicitly OUT of scope for the implementer (Fable does these after, funnel-in)\n\n- Edits to `scripts/proprioception.py` (guardian_freshness item + wrap registry entry)\n- Edits to `infra/healer/healer-run.sh` (receptor 4: run probe + transitions→ACTIONABLE + Telegram line)\n- `.github/workflows/immune-enforcement.yml` test wiring\n- `docs/runbooks/arsenal-probe.md`\n- PENDING-ARMS arming lines\n\n## Style contract\n\nPython 3.11 stdlib-only (subprocess, json, concurrent.futures, urllib.request for HTTP — no\nrequests dep), full type hints, logger-style stderr prints OK for a CLI tool, module docstring\nwith the one-line mission + scar references (#2 Esiste≠Armato, #4 secrets, W84 blind-scan).\nMatch the voice of `scripts/proprioception.py` (concise comments explaining WHY, not what).\n"}}, "docs/audits/2026-05-02-cell-openclaw-brainstorm/07_openclaw_deep_research.md": {"9e8bb6055c42e72817fc7b01bc5035a2a7b7bf41": {"t": 1785746582.731969, "n": 34193, "h": "c11e0bae09aa0645", "c": "# OpenClaw Deep Research: Architecture, Capabilities & Current Usage\n**Date**: 2026-05-02 | **Version**: openclaw 2026.3.31 | **Local Install**: `~/.openclaw/lib/node_modules/openclaw/` | **Config**: `~/.openclaw/openclaw.json`\n\n**Audience**: Claude (reader) + cross-LLM reviewers (Codex GPT-5.5, Gemini 3.1 Pro, DeepSeek V4 Reasoner) preparing to reason about OpenClaw's role in Nuzantara automations.\n\n---\n\n## Executive Summary\n\nOpenClaw is a **Node.js-based personal AI gateway** running a WebSocket control plane (`ws://127.0.0.1:18789`) that routes inbound messages from 23+ messaging channels (Telegram, WhatsApp, Discord, Slack, iMessage, etc.) to isolated agents, which dispatch LLM requests with multi-model fallback + tool streaming. The runtime is process-managed by LaunchAgent on macOS; the agent itself is embedded (RPC mode). \n\n**Nuzantara is using OpenClaw for**:\n- Primary messaging channel: Telegram (enabled, receiving message timeouts)\n- Multi-LLM routing: MiniMax M2.7 (primary) → Kimi K2.6 → DeepSeek Chat → Ollama Qwen3.5\n- Persistent memory: memory-core plugin (storing observations from tool use)\n- Orchestration: lobster plugin (workflow DSL, enabled)\n- Voice: voice-call skill (enabled)\n- Custom extensions: claude-mem (v12.1.0, marketplace install)\n\n**Version Gap**: Installed version is 2026.3.31 (released ~Mar 31); latest is 2026.4.29 (released Apr 30). Recent releases include Knowledge Agents system (12.1.0 in claude-mem), improved Telegram channel timeouts, and model failover hardening.\n\n---\n\n## A. Architecture\n\n### Runtime Model\n\nOpenClaw is a **Node.js daemon** (v22.22.0, bundled) running:\n- **Gateway** (port 18789, loopback-only, hybrid reload on config change)\n- **Control UI** (Web dashboard, http://127.0.0.1:18789)\n- **Pi agent** (embedded RPC, not external process)\n- **Channel adapters** (Telegram: grammY, Discord: discord.js, WhatsApp: Baileys, etc.)\n\n**Process Management**:\n- macOS: LaunchAgent (`~/Library/LaunchAgents/openclaw.plist` — managed by Nuzantara's `monitor-air.log` cron)\n- KeepAlive policy: checked via heartbeat monitor every 1h (Nuzantara config: `heartbeat.every=\"1h\"`)\n- Uptime target: 24/7 (threshold exceeded May 2, 2026 at 01:13 UTC — gap analysis in logs)\n\n### Agent Abstractions\n\n**Agent Definition** (`agents.list[]`):\n- Nuzantara has 2 agents:\n 1. **main**: primary, Telegram-bound, sandbox=off, model routing primary→fallback chain\n 2. **coder**: isolated workspace, sandbox=off, web tools denied (no web_search, web_fetch, browser)\n\n**Model Routing**:\n```\nmain:\n primary: openrouter/minimax/minimax-m2.7\n fallbacks: [kimi-k2.6, deepseek-chat, ollama/qwen3.5:9b]\n\ncoder:\n primary: openrouter/qwen/qwen3-max\n fallbacks: [qwen3.6-plus, kimi-k2.6, deepseek-reasoner, qwen3.5:9b]\n```\n\n**Fallback Chain Logic**:\n- Model request → try primary; if fails (auth, rate_limit, not_found) → try next fallback\n- Auth cooldown: 300s lockout after 10 auth failures in 60s window (gateway.auth.rateLimit)\n- Rate-limit cooldown: automatic provider cooldown (all-profiles-unavailable state) visible in logs (Mar 1-2, Google Gemini CLI exhausted)\n\n**Sandbox Modes**:\n- Default: `non-main` (separate container per agent workspace)\n- Nuzantara: `mode=off` for both agents (no isolation) + `prune.idleHours=24` (clean up idle containers)\n\n### Plugin System\n\nPlugins extend gateway capabilities via allow-list:\n\n**Loaded Plugins** (`plugins.entries`):\n- **memory-core** (enabled): observation feed + persistent storage\n- **memory-lancedb** (disabled): vector search backend (not active)\n- **lobster** (enabled): workflow orchestration DSL\n- **llm-task** (enabled): multi-step LLM orchestration\n- **voice-call** (enabled): phone/VOIP integration\n- **telegram** (implicit, channel adapter)\n\n**Plugin Trust Model**:\n- Plugins in `~/.openclaw/extensions/` are scanned; only those in `plugins.allow[]` are loaded\n- Nuzantara's installed plugin: `claude-mem` (v12.1.0) in `~/.openclaw/extensions/claude-mem/`\n- **Trust Warning**: claude-mem flagged in gateway logs as \"loaded without install/load-path provenance\" (implies manual fs install, not via package manager)\n\n### Skill System\n\nSkills add tools to agents via hooks + HTTP API.\n\n**Bundled Skills** (`~/.openclaw/lib/node_modules/openclaw/skills/`):\n- goplaces (Google Places API), xurl (URL shortener), voice-call (Twilio), notion, slack, discord, trello, spotify-player, etc.\n\n**Nuzantara Enabled Skills** (`skills.entries`):\n- **goplaces**: enabled (env: GOOGLE_PLACES_API_KEY)\n- **xurl**: enabled\n- **voice-call**: enabled\n- **notion**: enabled (env: NOTION_API_KEY)\n- **antigravity**: enabled\n\n**Custom Skills Directory**: `/Users/nuzantara/Desktop/nuzantara/apps/nuzantara-mcp/skills` (loaded via `skills.load.extraDirs[]`)\n\n### Channel Bindings\n\n**Telegram Channel** (enabled, dmPolicy=open):\n- **BotToken**: configured (redacted in config, present in plaintext)\n- **Allowed Senders**: `allowFrom=[\"*\"]` (open to all)\n- **Streaming**: disabled (responses sent as complete message blocks)\n- **Timeout**: 60s per message\n- **Retry**: 2 attempts, min 5s delay, max 60s delay, 0.5 jitter\n- **Known Issues**:\n - Network timeouts (ETIMEDOUT / EHOSTUNREACH observed Mar 1-2, 30s+ waits)\n - BOT_COMMANDS_TOO_MUCH (Telegram API limit: max 100 commands, Nuzantara registering 92-97, dropping 19-20 on each attempt)\n\n**Other Channels**:\n- WhatsApp, Discord, Slack, Signal, iMessage (BlueBubbles), IRC, Teams, Matrix: all disabled in config\n\n### Memory Model\n\n**memory-core** plugin:\n- SQLite database: `~/.openclaw/agents/main/agent/memory.db` (not visible in config, inferred from logs)\n- Observation feed: tool_use events → semantic summaries → injected into future sessions\n- Token-aware: context pruning mode=cache-ttl (1h TTL), compaction mode=safeguard (96k reserve floor, 40% history max)\n- Worker Service: runs on separate port (likely 37777 per claude-mem docs), managed by Bun\n- Vector backend: Chroma (if memory-lancedb enabled; currently off)\n\n### mcporter Integration\n\n**Tool Surface**:\n- Built-in: browser, canvas, nodes, cron, sessions\n- MCP tools: claude-mem (`search`, `timeline`, `get_observations`), custom skills\n\n**Safety Allowlist** (`tools.exec.safeBins[]`):\n```\nls, cat, tail, which, nuzantara-ops, mcporter\n```\n- Only these binaries can be executed without sandbox approval\n- `mcporter` is whitelisted (allows MCP tool invocation from agent)\n- **Known Issue**: mcporter allowlist audited Mar 22; safeBins entries not matching plugin config (audit log shows mismatch fixed via plugin reload)\n\n### Lobster Workflows\n\n**Lobster Plugin** (enabled):\n- DSL for multi-step orchestration\n- Workflow files: `~/.openclaw/workspace/.lobster/*.yml` (inferred)\n- Nuzantara logs show no active workflows, but plugin enabled for future use\n\n### Sandbox & Safety\n\n**Exec Approval Socket** (`exec-approvals.sock`):\n- Manual approval flow for unsafe commands\n- Not actively used in Nuzantara (sandbox=off, so no approvals needed)\n\n**Circuit Breaker** (`tools.loopDetection`):\n- Enabled globally (threshold=10 repeats)\n- Detectors:\n - **genericRepeat**: catch identical tool calls in sequence\n - **knownPollNoProgress**: detect polling without state change\n - **pingPong**: detect tool A → B → A cycles\n- Nuzantara: enabled, no circuit trips observed (logs clean on this metric)\n\n---\n\n## B. Current Capabilities\n\n### Agentic Tasks\n\n**Single-turn**: `openclaw agent --message \"query\"` (CLI or Gateway RPC)\n**Multi-turn**: Session state preserved in memory; model compaction + context pruning per config\n**Persistent Loops**: Supported via Lobster workflows (enabled but not in use)\n\n### Tool Use\n\n| Tool | Enabled | Notes |\n|------|---------|-------|\n| **web_search** | Yes | Integrated |\n| **web_fetch** | Yes | Integrated |\n| **browser** | No (coder agent denies) | Chrome control, snapshots, actions |\n| **exec** | Partial (safeBins only) | ls, cat, tail, nuzantara-ops, mcporter |\n| **file ops** | Via browser canvas | Not direct agent tool |\n| **image** | Yes (image model routing) | Primary: ollama/qwen2.5vl:7b, fallback: openrouter/qwen3-vl |\n| **canvas** (macOS) | Yes | A2UI protocol, push/reset/eval/snapshot |\n| **cron** | Yes | 24 jobs max (Nuzantara shows 0 active, scheduler may be frozen as of Apr 30) |\n| **custom MCP** | Yes (mcporter) | Route to local/remote MCP servers |\n\n**Multi-LLM Routing**: Each agent has primary + 3 fallback models; per-model params (temperature, max_tokens) configurable\n\n### Multi-LLM Routing\n\n**Provider Configuration**:\n- **openrouter**: native support, baseUrl=https://openrouter.ai/api/v1, 6 models configured\n- **deepseek**: native support, baseUrl=https://api.deepseek.com/v1, 2 models configured\n- **ollama**: local, baseUrl=http://127.0.0.1:11434, 0 models pre-configured (dynamic discovery)\n- **anthropic**: **NOT configured** (no ANTHROPIC_API_KEY in env; Nuzantara policy: banned)\n- **openai** (via openrouter): shim via openrouter provider\n\n**Per-Model Tuning**:\n```\ntemperature: 0.2–0.4 (reasoning), 0.3–0.4 (chat)\nmax_tokens: 4096–8192\nollama-specific: keep_alive=10m (memory cache), top_p=0.9, top_k=20\n```\n\n**Fallback Behavior**: \n- Try primary; if fails, cascade through fallbacks\n- Rate-limit cooldown (300s) applied per provider\n- Auth errors caught and retried with different auth profile (if multi-profile configured)\n\n### Persistent Memory\n\n**memory-core** (enabled):\n- **Lifecycle Hooks**: SessionStart → UserPromptSubmit → PostToolUse → Summary → SessionEnd\n- **Observation Compression**: tool_use events → semantic summaries (via Claude API or local LLM)\n- **Injection Strategy**: progressive disclosure (layer 1: index; layer 2: timeline; layer 3: full details)\n- **Search Tools**: `mem-search`, `timeline`, `get_observations` (MCP interface)\n- **Durability**: SQLite persistent store, survives session/process restarts\n\n### Channel I/O\n\n**Telegram** (primary):\n- Inbound: message events → matched to agent via binding (main agent, Telegram channel)\n- Outbound: agent reply → formatted as Telegram message → sent via botToken\n- **State**: connected (logs show recent message processing up to May 2 01:13)\n- **Timeouts**: retry logic (2 attempts, 5–60s backoff) masks network latency\n\n### Voice-Call\n\n**voice-call Skill** (enabled):\n- Integration: Twilio (inferred from OpenClaw docs; not explicitly in Nuzantara config)\n- Capabilities: accept voice calls, stream audio, TTS output (ElevenLabs or system fallback)\n- **Status in Nuzantara**: enabled but not actively tested\n\n### Browser Automation\n\n**Browser Tool** (available, not in use by main agent):\n- Chrome/Chromium control (dedicated OpenClaw instance)\n- Actions: snapshot, click, type, scroll, upload, profile switching\n- **Nuzantara**: coder agent has browser denied via `tools.deny=[\"browser\"]`\n\n### Workflow Orchestration (Lobster)\n\n**Lobster DSL** (enabled, not in active use):\n- YAML-based multi-step orchestration\n- Syntax: task dependencies, conditional routing, parallel execution\n- **Nuzantara**: loaded but no workflows observed in logs\n\n### Subagents\n\n**Subagent Pattern**: supported via agent routing (`bindings[]` match rules)\n- **Nuzantara**: 2 agents defined (main, coder); no inter-agent delegation observed\n- **Limitation**: agents are isolated; no direct parent-child RPC (agents are standalone)\n\n### Cron / Scheduled Jobs\n\n**Cron Tool**:\n- API: `POST /gateway/cron` or `openclaw cron add <schedule> <command>`\n- Max 24 jobs per gateway\n- **Nuzantara Status**: 0 active jobs logged (scheduler may be frozen since Apr 30 per audit notes)\n\n### Hooks\n\n**7 Lifecycle Hooks** (claude-mem):\n- SessionStart, UserPromptSubmit, PostToolUse, Summary, SessionEnd, PreToolUse, Stop\n- **Nuzantara Use**: memory-core hooks active (observation capture, summary generation)\n\n### Plugin Development\n\n**Plugin Template**:\n- Entry point: `plugin/index.ts` or `dist/index.js`\n- Hooks: export `hooks: { SessionStart, UserPromptSubmit, ... }`\n- MCP Tools: export `tools: [ ... ]` (JSON-RPC 2.0 interface)\n- **Nuzantara Custom Skills**: loaded from `/Users/nuzantara/Desktop/nuzantara/apps/nuzantara-mcp/skills/` (no plugins observed)\n\n### Embedded Agent Runtime\n\n**Pi Agent** (embedded, not delegated):\n- Runs in-process with gateway (RPC loopback)\n- Session state: maintained in gateway memory (not persistent across restarts without memory plugin)\n- Tool dispatch: streaming responses back to gateway → channel output\n\n---\n\n## C. What's NEW (Recent OpenClaw Releases)\n\n| Release | Date | Highlights |\n|---------|------|-----------|\n| **v2026.4.29** | Apr 30, 2026 | Stability improvements, auth profile migration docs |\n| **v2026.4.09** | Apr 9, 2026 | Knowledge Agents system (6 new MCP tools: build_corpus, prime_corpus, query_corpus, etc.) |\n| **v2026.3.31** | Mar 31, 2026 | **[INSTALLED]** DM pairing default, Telegram net timeout handling, provider enum changes |\n| **v2026.1.5** | Jan 5, 2026 | Image model config, agent.imageModel + fallbacks, model shorthands (opus, sonnet, gpt, gemini) |\n\n**Most Notable for Nuzantara**:\n- **Knowledge Agents** (v2026.4.09): Compile filtered corpus from claude-mem observations, query conversationally. 6 new MCP tools (build_corpus, list_corpora, prime_corpus, query_corpus, rebuild_corpus, reprime_corpus). **Not yet exploited.**\n- **Auth Profile Migration** (v2026.3.31 → v2026.4.29): DM pairing now default (requires approval codes); legacy \"open to all\" requires explicit dmPolicy=open + allowFrom=[\"*\"]. **Nuzantara already configured.**\n- **Telegram Timeout Hardening** (v2026.3.31): Retry + backoff for network errors (30s+ waits masked). **Experienced but handled gracefully.**\n\n**Claude-Mem Integration** (v12.1.0, installed via marketplace):\n- Knowledge agents now supported (native corpus build, prime, query MCP tools)\n- Smart-explore extended to 24 languages\n- File-read decision gate (PreToolUse hook blocks redundant reads using observation timeline)\n\n---\n\n## D. Comparison vs Alternatives\n\n| Dimension | OpenClaw | cron-agent-python (Nuzantara) | LangChain/LangGraph | Anthropic Agent SDK (direct) |\n|-----------|----------|------|-----------|---------|\n| **Primary UX** | Gateway + multi-channel | Python cron + custom CLI | Chain/graph DSL | Messages API |\n| **Multi-LLM** | Native (fallback chains) | Manual (explicit per-agent config) | LLMChain abstraction | No native support |\n| **Persistent Memory** | Plugin-based (memory-core) | NotebookLM (external) | No built-in | No built-in |\n| **Channel Binding** | 23+ integrations (Telegram, Discord, etc.) | CLI-only / webhooks | None (user's responsibility) | None |\n| **Workflow Orchestration** | Lobster DSL | Python task queue | LangGraph (DAG-based) | Claude Agent SDK (new) |\n| **Tool Streaming** | Yes (block streaming) | Manual | Yes (via tool classes) | Yes (native) |\n| **Sandbox** | Exec approval socket | None (direct subprocess) | None | None (external runner) |\n| **State Persistence** | SQLite (via plugins) | Disk-backed (JSON/state files) | Not built-in | Not built-in |\n| **Scaling** | Single gateway (local) | Multi-machine (cron dispatch) | App-level (doesn't scale infra) | Delegated to cloud provider |\n| **Ease of Setup** | `openclaw onboard` (90s) | Python venv + config | npm install + boilerplate | anthropic SDK (Python/JS) |\n\n**OpenClaw's Unique Value Propositions**:\n1. **Multi-channel inbox**: Single control plane for Telegram, WhatsApp, Discord, Slack, iMessage, IRC, Teams, Signal, etc.\n2. **Persistence out-of-the-box**: memory-core plugin captures observations + injects into future sessions (no manual logging)\n3. **Native fallback chains**: multi-model routing with per-provider cooldowns + auth management\n4. **Embedded + local**: runs on your machine (no cloud), binds to loopback only (no public expose by default)\n\n**Where OpenClaw Loses**:\n1. **No cloud sync**: single-machine deployment (no multi-region HA out of the box)\n2. **Provider enum rigidity**: only supports explicit providers (openrouter, deepseek, ollama, anthropic); no generic OpenAI-compatible override until v2026.3.31+ (baseUrl interpolation)\n3. **Command limit (Telegram)**: max 100 commands registered; Nuzantara hitting 92-97, dropping 19-20 on each sync\n4. **Scheduler frozen** (apr 30+): cron jobs not running (24-job queue inert); cause unknown\n\n**vs cron-agent-python** (Nuzantara parallel):\n- cron-agent-python: 19 active strategies, each runs independently on schedule; state decoupled (disk-backed JSON)\n- OpenClaw: single agent with multi-LLM routing; state unified in memory-core\n- **Recommendation**: cron-agent-python excels for **independent, scheduled tasks** (classification, analysis per-document); OpenClaw excels for **interactive, multi-turn conversations** with memory (Telegram chatbot + persistent context)\n\n---\n\n## E. Scaling Characteristics\n\n### Concurrency\n\n**Max Concurrent Agents**: 1 gateway, N agents (in Nuzantara: 2)\n- **Per-Agent Sessions**: Unbounded (session state pruned on demand)\n- **Concurrent Requests**: Limited by LLM provider rate limits (OpenRouter: ~100 req/min; DeepSeek: API doc unclear; Ollama: local, unbounded)\n- **Telegram Message Queue**: Sequential (one message processed at a time, 60s timeout → retry → backoff)\n\n### Memory Footprint\n\n| Component | RSS (Idle) | RSS (Active) | Notes |\n|-----------|-----------|-------------|-------|\n| Gateway process | ~200–300 MB | ~400–600 MB | Node.js runtime + channel adapters |\n| memory-core SQLite | ~10 MB | ~50+ MB | Depends on observation count + vector index |\n| Chroma (if enabled) | N/A | ~200+ MB | Python subprocess (uv-managed), not active in Nuzantara |\n| Total (Nuzantara) | ~250 MB | ~500+ MB | Measured via LaunchAgent memory monitor |\n\n### Latency Overhead\n\n| Operation | Latency | Notes |\n|-----------|---------|-------|\n| Gateway routing (inbound message) | <10ms | WebSocket demux + binding match |\n| Agent dispatch (to LLM) | <50ms | HTTP to OpenRouter/DeepSeek |\n| LLM request | 500ms–5s | Depends on model, fallback chain depth |\n| Response streaming (Telegram) | 1–30s | Tool execution + LLM generation + retry backoff |\n| Memory injection (PreToolUse) | 100–500ms | SQLite query + compression (if observation reuse) |\n\n**Gateway overhead is negligible** (<10% of E2E latency).\n\n### State Persistence\n\n**Durable Across Crashes**: Yes (if memory-core enabled)\n- Session state saved to SQLite after each tool_use hook\n- Observation timeline reconstructed on SessionStart\n\n**Graceful Shutdown**: LaunchAgent KeepAlive policy\n- monitored by `launchctl unload/load` (manual) or cron watchdog (Nuzantara)\n- Timeout: 30s (hard kill if not responsive)\n\n### Crash Recovery\n\n**KeepAlive=true** (Nuzantara config):\n- LaunchAgent auto-restarts gateway on exit (non-zero exit code)\n- State surviving: memory-core observations (durable), in-flight messages (lost, retried by Telegram)\n- **Observed**: gateway crashes not logged; LaunchAgent restarts appear transparent\n\n### Multi-Instance Topology\n\n**Federation**: Not supported natively\n- **Workaround**: run multiple gateways on different ports (18789, 18790, ...), but agents are isolated per gateway\n- **Nuzantara**: single gateway (port 18789); no multi-instance setup\n\n---\n\n## F. Security Model\n\n### Loopback-Only Binding\n\n**gateway.bind=loopback** (Nuzantara default):\n- Gateway listens on 127.0.0.1:18789 (localhost only)\n- No public internet exposure (requires SSH tunnel or Tailscale to access from remote)\n- **Threat Model**: protects against direct internet attacks; assumes local machine is secure\n\n### Auth Token & Rate Limiting\n\n**Token** (gateway.auth.token):\n- Long random string (example: 64 char base64)\n- Required in WebSocket `?token=...` query param or HTTP `Authorization: Bearer <token>` header\n- **Storage**: plaintext in `~/.openclaw/openclaw.json` (same permissions as SQLite DB)\n- **Rotation**: manual edit + `openclaw reload` (no auto-rotation tool visible)\n\n**Rate Limiting**:\n- **maxAttempts**: 10 failures in 60s window (Nuzantara config)\n- **lockoutMs**: 300s (5 min) lockout after threshold\n- **Scope**: per-IP (loopback is single IP, so affects all local clients equally)\n\n### exec-approvals.sock\n\n**Manual Approval Flow**:\n- Unsafe exec commands → `exec-approvals.sock` (Unix domain socket, `/tmp/exec-approvals-<pid>.sock`)\n- User approval via CLI: `echo \"approve <exec-id>\" | nc -U /tmp/exec-approvals-<pid>.sock`\n- **Nuzantara Status**: sandbox=off for both agents, so approval flow never triggered\n\n### Sandbox Modes\n\n| Mode | Isolation | Use Case |\n|------|-----------|----------|\n| **off** | None | Development, trusted local use |\n| **non-main** | Per-agent container | Multi-agent isolation (default agents.defaults.sandbox.mode) |\n| **full** | Per-session container | Maximum isolation (experimental) |\n\n**Nuzantara**: mode=off (no isolation). Rationale: single user, local machine, trusted workflows. Trade-off: agents can interfere (shared filesystem, process space).\n\n### Safety Bins Allowlist\n\n**Tools.exec.safeBins**:\n```\nls, cat, tail, which, nuzantara-ops, mcporter\n```\n- Only these binaries bypass approval flow\n- Others require exec approval (if sandbox=non-main or full)\n- **Known Issue** (Mar 22): safeBins not matching plugin config; resolved via plugin reload\n\n**Attack Surface**: agent can only run safe binaries; can't execute arbitrary commands (unless sandbox=off + agent has write access to filesystem, which it does in Nuzantara)\n\n### Plugin Trust Model\n\n**Plugin Loading** (`plugins.allow[]`):\n- Whitelist-based: only plugins in allow-list are loaded\n- Nuzantara loads: memory-core, lobster, llm-task, voice-call (implicit)\n- claude-mem: loaded from `~/.openclaw/extensions/claude-mem/` (manual install, not in core plugins.allow)\n\n**Trust Signals**:\n- Official plugins: signed releases, open-source GitHub\n- User plugins (Nuzantara custom skills): loaded from `/Desktop/nuzantara/apps/nuzantara-mcp/skills/` (same machine, implicit trust)\n- **Warning**: claude-mem flagged as \"loaded without install/load-path provenance\" → suggests side-load outside normal package path\n\n### Secret Handling\n\n**API Key Interpolation**:\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"${OPENROUTER_API_KEY}\"\n }\n }\n}\n```\n\n**Resolution**:\n1. Check environment variable (shellEnv=true in Nuzantara config, shell timeout 15s)\n2. Check EnvironmentVariables from LaunchAgent plist (if running as daemon)\n3. Fall back to plaintext in config (NOT recommended)\n\n**Nuzantara Config**:\n- OPENROUTER_API_KEY, DEEPSEEK_API_KEY, GOOGLE_PLACES_API_KEY, NOTION_API_KEY → in `~/.openclaw/.env` (not shown, but inferred from skills.env)\n- **Risk**: if `.env` checked into git, keys exposed\n\n---\n\n## G. Operational Model\n\n### LaunchAgent Management\n\n**Service File**: `~/Library/LaunchAgents/openclaw.plist` (macOS)\n- **Label**: com.openclaw.daemon\n- **Program**: node (bundled in ~/.openclaw/tools/node-v22.22.0/bin/node)\n- **KeepAlive**: true (auto-restart on exit)\n- **ThrottleInterval**: 30s (min time between restarts after crash)\n- **RunAtLoad**: true (start on login)\n\n**Manual Control**:\n```bash\nlaunchctl load ~/Library/LaunchAgents/openclaw.plist\nlaunchctl unload ~/Library/LaunchAgents/openclaw.plist\nlaunchctl start com.openclaw.daemon\nlaunchctl stop com.openclaw.daemon\n```\n\n**Nuzantara Monitoring**: cron job `monitor-air.log` (implied by logs; monitors for crashes + auto-restart failures)\n\n### Logs\n\n| Log | Path | Rotation | Notes |\n|-----|------|----------|-------|\n| **gateway.log** | `~/.openclaw/logs/gateway.log` | Yes (daily) | Main diagnostic output (diagnostic, channel, agent events) |\n| **gateway.err.log** | `~/.openclaw/logs/gateway.err.log` | Yes (daily) | Errors, warnings, stack traces |\n| **commands.log** | `~/.openclaw/logs/commands.log` | N/A | Slash command executions |\n| **config-audit.jsonl** | `~/.openclaw/logs/config-audit.jsonl` | Append | Config change audit trail |\n\n**Log Level**: `logging.level=info` (Nuzantara config); controlled via `openclaw config set logging.level=debug` (or restart with env var)\n\n**Retention**: no explicit TTL in config; logs grow unbounded (gateway.log: 21.7 GB as of May 2, gateway.err.log: 288 MB). **Risk**: disk space exhaustion.\n\n### Health Endpoint\n\n**Endpoint**: `GET /healthz` (Gateway)\n- **Response**: `{ \"status\": \"ok\" }` (200 OK) or 500 on error\n- **Nuzantara Use**: implied by monitor-air; likely polled every 5–60s\n\n### Metrics Export\n\n**Prometheus**: Not built-in to OpenClaw (as of v2026.3.31)\n- **Workaround**: parse logs with regex + ship to external metrics service\n- **Nuzantara**: no custom metrics exporter observed\n\n### Debugging\n\n**Verbose Mode**: `openclaw gateway --verbose` (CLI flag)\n**Log Level Override**: `OPENCLAW_LOG_LEVEL=debug` (env var at startup)\n**RPC Tracing**: gateway logs all RPC calls (agent → channel) with stack traces on failure\n\n**Trace an Agent Decision**:\n1. Enable debug logging\n2. Send message via Telegram\n3. Check gateway.log for SessionStart → UserPromptSubmit → tool_use → agent response flow\n4. Correlate with memory-core observations (check `.openclaw/agents/main/agent/memory.db` if needed)\n\n### Update Process\n\n**Manual Update**:\n```bash\nnpm install -g openclaw@latest\nopenclaw onboard --update # or --install-daemon to refresh daemon\n```\n\n**Safe Update (Nuzantara)**:\n1. `launchctl stop com.openclaw.daemon` (halt gateway)\n2. Backup `~/.openclaw/openclaw.json` + `~/.openclaw/workspace/`\n3. `npm install -g openclaw@latest`\n4. Review CHANGELOG for breaking changes\n5. Run `openclaw doctor` (auto-migrate config if needed)\n6. `launchctl start com.openclaw.daemon` (restart)\n\n**Auto-Update**: Not configurable in v2026.3.31; manual only.\n\n---\n\n## H. Known Issues & Pitfalls\n\n### 1. Provider Enum Rigidity\n\n**Issue**: openai-completions API wrapper only recognizes explicit `api: \"openai\"` (no generic override)\n\n**Impact**: Can't use arbitrary OpenAI-compatible backends (e.g., vLLM, LocalAI) without forking\n\n**Workaround** (Nuzantara): Use `api: \"openai-completions\"` with openrouter shim (all models exposed via openrouter baseURL)\n\n**Status**: Likely fixed in v2026.4.29 (baseUrl interpolation mentioned in changelog), but not tested against Nuzantara's installed v2026.3.31\n\n### 2. Secret Interpolation (`${VAR}` Only in env)\n\n**Issue**: `apiKey: \"${VAR}\"` resolves ONLY if VAR is in EnvironmentVariables (from LaunchAgent plist or shell env at startup), NOT from `.env` file or inline plaintext\n\n**Impact**: Easy to forget to export env var → silent fallback to missing key → auth failures\n\n**Example** (Nuzantara):\n```json\n{\n \"openrouter\": {\n \"apiKey\": \"${OPENROUTER_API_KEY}\" // resolves to env var if set, else null\n }\n}\n```\n\n**Workaround**: Explicitly set in LaunchAgent plist `EnvironmentVariables` section or `source ~/.openclaw/.env` before `launchctl load`\n\n### 3. mcporter Allowlist Quirks\n\n**Issue** (Mar 22 audit log): safeBins entries `ls, cat, tail, which, nuzantara-ops, mcporter` not matching plugin config → mcporter tool calls rejected\n\n**Root Cause**: Plugin loading race condition (safeBins checked before plugin registration completes)\n\n**Status**: Resolved in Nuzantara by manual reload (launchctl stop/start)\n\n**Fix Expected**: v2026.4.29+ (not tested)\n\n### 4. Plugin Trust Warnings\n\n**Issue**: claude-mem loaded from `~/.openclaw/extensions/claude-mem/` without install/load-path provenance\n\n**Impact**: Minor (code review recommended for untrusted sources); claude-mem is open-source + widely used\n\n### 5. Telegram Network Timeouts\n\n**Issue**: `getUpdates` request times out after 30s; retry backoff (5s → 60s) masks latency but creates gaps in message delivery (Apr 30 + May 2 logs show repeated timeouts)\n\n**Impact**: Inbound messages may be delayed 30–120s during network flaps\n\n**Cause**: Likely ISP or Telegram API throttling (Nuzantara in Bali, geographically distant from Telegram servers)\n\n**Workaround**: Increase timeout (Telegram: `timeoutSeconds=120`) or use webhook polling (if supported in next version)\n\n**Status**: Retry logic + backoff now in v2026.3.31; gracefully handled but not ideal UX\n\n### 6. BOT_COMMANDS_TOO_MUCH (Telegram API Limit)\n\n**Issue**: Telegram API limits /command menu to 100 entries; Nuzantara registering 92–97 commands (skills + custom), dropping 19–20 on each sync\n\n**Impact**: Some skills unavailable in Telegram /command autocomplete menu (but still callable via message mention)\n\n**Log Evidence**:\n```\n[telegram] rejected 92 commands (BOT_COMMANDS_TOO_MUCH); retrying with 73.\n[telegram] accepted 73 commands after BOT_COMMANDS_TOO_MUCH (started with 92; omitted 19).\n```\n\n**Root Cause**: Too many skills enabled (goplaces, xurl, voice-call, notion, antigravity) + OpenClaw bundled commands\n\n**Workaround**: Disable low-use skills in `skills.entries` (set enabled=false for unused ones)\n\n**Fix**: None in OpenClaw core (Telegram API limit). Requires operator intervention.\n\n### 7. Scheduler Frozen (Apr 30+)\n\n**Issue**: Cron jobs not running; 24-job queue inert\n\n**Evidence**: No cron logs in gateway.log since Apr 30; cron tool still responds to queries but doesn't execute\n\n**Impact**: Scheduled tasks (batch processing, daily summaries) missed\n\n**Likely Cause**: \n- Scheduler process crash (separate thread)\n- Job queue lock contention\n- State corruption after config reload\n\n**Status**: Unknown (no debugging done); requires `openclaw doctor` + manual job purge/recreate\n\n**Workaround**: Migrate to external cron runner (separate Python process with its own scheduler) or upgrade to v2026.4.29+\n\n### 8. Context Compaction False Positives\n\n**Issue**: context pruning + compaction may discard relevant observations if TTL expires before session end\n\n**Config** (Nuzantara):\n```\ncontextPruning.mode=cache-ttl, ttl=1h\ncompaction.mode=safeguard, reserveTokensFloor=96k\n```\n\n**Impact**: Multi-day sessions lose early context after 1h, even if still relevant\n\n**Workaround**: Increase TTL to 24h or use `mode: \"never\"` (disables pruning, risks context explosion)\n\n---\n\n## I. Roadmap & Future Direction\n\n**Public Roadmap**: https://github.com/openclaw/openclaw/issues (GitHub Issues, no official roadmap doc)\n\n**Recent PR Signals** (inferred from changelog):\n- **Knowledge Agents** (v2026.4.09): Building queryable \"brains\" from observation history (corpus build + prime + query)\n- **Auth Profile System** (v2026.3.31+): Multi-profile support + role-based failover (not fully enabled in Nuzantara)\n- **DM Pairing Security**: Default dmPolicy=pairing (require approval code for unknown senders) — security-first direction\n- **Provider Enum Expansion**: Support for more providers + generic OpenAI-compatible override (v2026.4.29 changelog hints)\n\n**Likely Future Work** (speculative):\n1. **Cloud Sync**: Multi-region HA + state replication (not in current roadmap, but enterprise feature request)\n2. **Structured Output**: Typed tool responses (Zod schema validation) — currently working, likely formalization\n3. **Voice Wake Improvements**: More language support, custom wake words (v2026.3.31 has voice-call, room for improvement)\n4. **Scheduler Stability**: Fix cron job queue race conditions (based on Apr 30 frozen state)\n5. **Knowledge Agent UI**: Web viewer for corpus browsing + semantic search (claude-mem v12.1.0 foundation)\n\n---\n\n## Summary Table: What Nuzantara Is Using vs. Available\n\n| Feature | Available | Enabled | Status |\n|---------|-----------|---------|--------|\n| **Multi-LLM Routing** | Yes (4 providers) | Yes (fallback chain) | Working, no issues |\n| **Persistent Memory** | Yes (memory-core) | Yes | Working, observations injected |\n| **Telegram Channel** | Yes | Yes | Working, but network timeouts every 30s+ |\n| **Workflow Orchestration** | Yes (Lobster) | Enabled but unused | Ready to use, no barriers |\n| **Knowledge Agents** | Yes (new in v12.1.0) | No | **NOT EXPLOITED** (v2026.4.09 feature) |\n| **Voice-Call Integration** | Yes | Yes | Enabled, not actively tested |\n| **Browser Automation** | Yes (main agent denied) | Partial (coder agent) | Available for coder agent |\n| **Cron Scheduler** | Yes (24 job limit) | Yes but frozen | **BROKEN** since Apr 30 |\n| **Custom Skills** | Yes (extraDirs) | Partially | `/nuzantara-mcp/skills/` not fully synced |\n| **Canvas (macOS)** | Yes | Implicit | Available if using macOS |\n| **Multi-Channel** | Yes (23 channels) | Only Telegram | Others disabled; can be enabled |\n\n---\n\n## Recommendations for Nuzantara\n\n1. **Upgrade to v2026.4.29** (from v2026.3.31): Knowledge Agents system ready; cron scheduler likely fixed; auth profiles stabilized\n2. **Exploit Knowledge Agents**: Build corpus from claude-mem observations; enable conversational history replay (query_corpus tool)\n3. **Fix Cron Scheduler**: Debug Apr 30 freeze; if unresolved in v2026.4.29, fallback to external cron-agent-python runner\n4. **Reduce Telegram Commands**: Disable unused skills (elite-longterm-memory, bluebubbles, discord, slack, spotify, trello) to stay under 100-command limit\n5. **Increase Telegram Timeout**: Raise `timeoutSeconds=120` to mask network latency (or implement webhook polling in next OpenClaw version)\n6. **Monitor Memory Growth**: Track `~/.openclaw/logs/gateway.log` size (currently 21.7 GB); implement log rotation or external log shipping\n7. **Test Voice-Call Skill**: Verify Twilio integration if voice interaction is planned\n8. **Sync Custom Skills**: Ensure `/nuzantara-mcp/skills/` fully registered with OpenClaw (check skills.entries for all custom entries)\n\n---\n\n## Files Referenced\n\n- **Config**: `/Users/nuzantara/.openclaw/openclaw.json` (v2026.3.31 schema)\n- **Installation**: `/Users/nuzantara/.openclaw/lib/node_modules/openclaw/`\n- **Logs**: `~/.openclaw/logs/gateway.log`, `gateway.err.log`\n- **Memory DB**: `~/.openclaw/agents/main/agent/memory.db` (SQLite, not visible in config)\n- **Workspace**: `~/.openclaw/workspace/` (markdown docs + agent state)\n- **Extensions**: `~/.openclaw/extensions/claude-mem/` (installed plugin)\n- **GitHub**: https://github.com/openclaw/openclaw (releases, issues, docs)\n- **Documentation**: https://docs.openclaw.ai (official, updated for v2026.4.29)\n- **claude-mem Marketplace**: `/Users/nuzantara/.claude/plugins/marketplaces/thedotmack/` (v12.1.0, AGPL-3.0)\n\n---\n\n**Document Compiled**: 2026-05-02 13:20 UTC | **Last Config Change**: 2026-05-02 13:20 UTC (Nuzantara-reported version)\n"}, "72ea7583cf1584a3b46956c063f0e71e069e04bb": {"t": 1785758295.7772791, "n": 34193, "h": "c11e0bae09aa0645", "c": "# OpenClaw Deep Research: Architecture, Capabilities & Current Usage\n**Date**: 2026-05-02 | **Version**: openclaw 2026.3.31 | **Local Install**: `~/.openclaw/lib/node_modules/openclaw/` | **Config**: `~/.openclaw/openclaw.json`\n\n**Audience**: Claude (reader) + cross-LLM reviewers (Codex GPT-5.5, Gemini 3.1 Pro, DeepSeek V4 Reasoner) preparing to reason about OpenClaw's role in Nuzantara automations.\n\n---\n\n## Executive Summary\n\nOpenClaw is a **Node.js-based personal AI gateway** running a WebSocket control plane (`ws://127.0.0.1:18789`) that routes inbound messages from 23+ messaging channels (Telegram, WhatsApp, Discord, Slack, iMessage, etc.) to isolated agents, which dispatch LLM requests with multi-model fallback + tool streaming. The runtime is process-managed by LaunchAgent on macOS; the agent itself is embedded (RPC mode). \n\n**Nuzantara is using OpenClaw for**:\n- Primary messaging channel: Telegram (enabled, receiving message timeouts)\n- Multi-LLM routing: MiniMax M2.7 (primary) → Kimi K2.6 → DeepSeek Chat → Ollama Qwen3.5\n- Persistent memory: memory-core plugin (storing observations from tool use)\n- Orchestration: lobster plugin (workflow DSL, enabled)\n- Voice: voice-call skill (enabled)\n- Custom extensions: claude-mem (v12.1.0, marketplace install)\n\n**Version Gap**: Installed version is 2026.3.31 (released ~Mar 31); latest is 2026.4.29 (released Apr 30). Recent releases include Knowledge Agents system (12.1.0 in claude-mem), improved Telegram channel timeouts, and model failover hardening.\n\n---\n\n## A. Architecture\n\n### Runtime Model\n\nOpenClaw is a **Node.js daemon** (v22.22.0, bundled) running:\n- **Gateway** (port 18789, loopback-only, hybrid reload on config change)\n- **Control UI** (Web dashboard, http://127.0.0.1:18789)\n- **Pi agent** (embedded RPC, not external process)\n- **Channel adapters** (Telegram: grammY, Discord: discord.js, WhatsApp: Baileys, etc.)\n\n**Process Management**:\n- macOS: LaunchAgent (`~/Library/LaunchAgents/openclaw.plist` — managed by Nuzantara's `monitor-air.log` cron)\n- KeepAlive policy: checked via heartbeat monitor every 1h (Nuzantara config: `heartbeat.every=\"1h\"`)\n- Uptime target: 24/7 (threshold exceeded May 2, 2026 at 01:13 UTC — gap analysis in logs)\n\n### Agent Abstractions\n\n**Agent Definition** (`agents.list[]`):\n- Nuzantara has 2 agents:\n 1. **main**: primary, Telegram-bound, sandbox=off, model routing primary→fallback chain\n 2. **coder**: isolated workspace, sandbox=off, web tools denied (no web_search, web_fetch, browser)\n\n**Model Routing**:\n```\nmain:\n primary: openrouter/minimax/minimax-m2.7\n fallbacks: [kimi-k2.6, deepseek-chat, ollama/qwen3.5:9b]\n\ncoder:\n primary: openrouter/qwen/qwen3-max\n fallbacks: [qwen3.6-plus, kimi-k2.6, deepseek-reasoner, qwen3.5:9b]\n```\n\n**Fallback Chain Logic**:\n- Model request → try primary; if fails (auth, rate_limit, not_found) → try next fallback\n- Auth cooldown: 300s lockout after 10 auth failures in 60s window (gateway.auth.rateLimit)\n- Rate-limit cooldown: automatic provider cooldown (all-profiles-unavailable state) visible in logs (Mar 1-2, Google Gemini CLI exhausted)\n\n**Sandbox Modes**:\n- Default: `non-main` (separate container per agent workspace)\n- Nuzantara: `mode=off` for both agents (no isolation) + `prune.idleHours=24` (clean up idle containers)\n\n### Plugin System\n\nPlugins extend gateway capabilities via allow-list:\n\n**Loaded Plugins** (`plugins.entries`):\n- **memory-core** (enabled): observation feed + persistent storage\n- **memory-lancedb** (disabled): vector search backend (not active)\n- **lobster** (enabled): workflow orchestration DSL\n- **llm-task** (enabled): multi-step LLM orchestration\n- **voice-call** (enabled): phone/VOIP integration\n- **telegram** (implicit, channel adapter)\n\n**Plugin Trust Model**:\n- Plugins in `~/.openclaw/extensions/` are scanned; only those in `plugins.allow[]` are loaded\n- Nuzantara's installed plugin: `claude-mem` (v12.1.0) in `~/.openclaw/extensions/claude-mem/`\n- **Trust Warning**: claude-mem flagged in gateway logs as \"loaded without install/load-path provenance\" (implies manual fs install, not via package manager)\n\n### Skill System\n\nSkills add tools to agents via hooks + HTTP API.\n\n**Bundled Skills** (`~/.openclaw/lib/node_modules/openclaw/skills/`):\n- goplaces (Google Places API), xurl (URL shortener), voice-call (Twilio), notion, slack, discord, trello, spotify-player, etc.\n\n**Nuzantara Enabled Skills** (`skills.entries`):\n- **goplaces**: enabled (env: GOOGLE_PLACES_API_KEY)\n- **xurl**: enabled\n- **voice-call**: enabled\n- **notion**: enabled (env: NOTION_API_KEY)\n- **antigravity**: enabled\n\n**Custom Skills Directory**: `/Users/nuzantara/Desktop/nuzantara/apps/nuzantara-mcp/skills` (loaded via `skills.load.extraDirs[]`)\n\n### Channel Bindings\n\n**Telegram Channel** (enabled, dmPolicy=open):\n- **BotToken**: configured (redacted in config, present in plaintext)\n- **Allowed Senders**: `allowFrom=[\"*\"]` (open to all)\n- **Streaming**: disabled (responses sent as complete message blocks)\n- **Timeout**: 60s per message\n- **Retry**: 2 attempts, min 5s delay, max 60s delay, 0.5 jitter\n- **Known Issues**:\n - Network timeouts (ETIMEDOUT / EHOSTUNREACH observed Mar 1-2, 30s+ waits)\n - BOT_COMMANDS_TOO_MUCH (Telegram API limit: max 100 commands, Nuzantara registering 92-97, dropping 19-20 on each attempt)\n\n**Other Channels**:\n- WhatsApp, Discord, Slack, Signal, iMessage (BlueBubbles), IRC, Teams, Matrix: all disabled in config\n\n### Memory Model\n\n**memory-core** plugin:\n- SQLite database: `~/.openclaw/agents/main/agent/memory.db` (not visible in config, inferred from logs)\n- Observation feed: tool_use events → semantic summaries → injected into future sessions\n- Token-aware: context pruning mode=cache-ttl (1h TTL), compaction mode=safeguard (96k reserve floor, 40% history max)\n- Worker Service: runs on separate port (likely 37777 per claude-mem docs), managed by Bun\n- Vector backend: Chroma (if memory-lancedb enabled; currently off)\n\n### mcporter Integration\n\n**Tool Surface**:\n- Built-in: browser, canvas, nodes, cron, sessions\n- MCP tools: claude-mem (`search`, `timeline`, `get_observations`), custom skills\n\n**Safety Allowlist** (`tools.exec.safeBins[]`):\n```\nls, cat, tail, which, nuzantara-ops, mcporter\n```\n- Only these binaries can be executed without sandbox approval\n- `mcporter` is whitelisted (allows MCP tool invocation from agent)\n- **Known Issue**: mcporter allowlist audited Mar 22; safeBins entries not matching plugin config (audit log shows mismatch fixed via plugin reload)\n\n### Lobster Workflows\n\n**Lobster Plugin** (enabled):\n- DSL for multi-step orchestration\n- Workflow files: `~/.openclaw/workspace/.lobster/*.yml` (inferred)\n- Nuzantara logs show no active workflows, but plugin enabled for future use\n\n### Sandbox & Safety\n\n**Exec Approval Socket** (`exec-approvals.sock`):\n- Manual approval flow for unsafe commands\n- Not actively used in Nuzantara (sandbox=off, so no approvals needed)\n\n**Circuit Breaker** (`tools.loopDetection`):\n- Enabled globally (threshold=10 repeats)\n- Detectors:\n - **genericRepeat**: catch identical tool calls in sequence\n - **knownPollNoProgress**: detect polling without state change\n - **pingPong**: detect tool A → B → A cycles\n- Nuzantara: enabled, no circuit trips observed (logs clean on this metric)\n\n---\n\n## B. Current Capabilities\n\n### Agentic Tasks\n\n**Single-turn**: `openclaw agent --message \"query\"` (CLI or Gateway RPC)\n**Multi-turn**: Session state preserved in memory; model compaction + context pruning per config\n**Persistent Loops**: Supported via Lobster workflows (enabled but not in use)\n\n### Tool Use\n\n| Tool | Enabled | Notes |\n|------|---------|-------|\n| **web_search** | Yes | Integrated |\n| **web_fetch** | Yes | Integrated |\n| **browser** | No (coder agent denies) | Chrome control, snapshots, actions |\n| **exec** | Partial (safeBins only) | ls, cat, tail, nuzantara-ops, mcporter |\n| **file ops** | Via browser canvas | Not direct agent tool |\n| **image** | Yes (image model routing) | Primary: ollama/qwen2.5vl:7b, fallback: openrouter/qwen3-vl |\n| **canvas** (macOS) | Yes | A2UI protocol, push/reset/eval/snapshot |\n| **cron** | Yes | 24 jobs max (Nuzantara shows 0 active, scheduler may be frozen as of Apr 30) |\n| **custom MCP** | Yes (mcporter) | Route to local/remote MCP servers |\n\n**Multi-LLM Routing**: Each agent has primary + 3 fallback models; per-model params (temperature, max_tokens) configurable\n\n### Multi-LLM Routing\n\n**Provider Configuration**:\n- **openrouter**: native support, baseUrl=https://openrouter.ai/api/v1, 6 models configured\n- **deepseek**: native support, baseUrl=https://api.deepseek.com/v1, 2 models configured\n- **ollama**: local, baseUrl=http://127.0.0.1:11434, 0 models pre-configured (dynamic discovery)\n- **anthropic**: **NOT configured** (no ANTHROPIC_API_KEY in env; Nuzantara policy: banned)\n- **openai** (via openrouter): shim via openrouter provider\n\n**Per-Model Tuning**:\n```\ntemperature: 0.2–0.4 (reasoning), 0.3–0.4 (chat)\nmax_tokens: 4096–8192\nollama-specific: keep_alive=10m (memory cache), top_p=0.9, top_k=20\n```\n\n**Fallback Behavior**: \n- Try primary; if fails, cascade through fallbacks\n- Rate-limit cooldown (300s) applied per provider\n- Auth errors caught and retried with different auth profile (if multi-profile configured)\n\n### Persistent Memory\n\n**memory-core** (enabled):\n- **Lifecycle Hooks**: SessionStart → UserPromptSubmit → PostToolUse → Summary → SessionEnd\n- **Observation Compression**: tool_use events → semantic summaries (via Claude API or local LLM)\n- **Injection Strategy**: progressive disclosure (layer 1: index; layer 2: timeline; layer 3: full details)\n- **Search Tools**: `mem-search`, `timeline`, `get_observations` (MCP interface)\n- **Durability**: SQLite persistent store, survives session/process restarts\n\n### Channel I/O\n\n**Telegram** (primary):\n- Inbound: message events → matched to agent via binding (main agent, Telegram channel)\n- Outbound: agent reply → formatted as Telegram message → sent via botToken\n- **State**: connected (logs show recent message processing up to May 2 01:13)\n- **Timeouts**: retry logic (2 attempts, 5–60s backoff) masks network latency\n\n### Voice-Call\n\n**voice-call Skill** (enabled):\n- Integration: Twilio (inferred from OpenClaw docs; not explicitly in Nuzantara config)\n- Capabilities: accept voice calls, stream audio, TTS output (ElevenLabs or system fallback)\n- **Status in Nuzantara**: enabled but not actively tested\n\n### Browser Automation\n\n**Browser Tool** (available, not in use by main agent):\n- Chrome/Chromium control (dedicated OpenClaw instance)\n- Actions: snapshot, click, type, scroll, upload, profile switching\n- **Nuzantara**: coder agent has browser denied via `tools.deny=[\"browser\"]`\n\n### Workflow Orchestration (Lobster)\n\n**Lobster DSL** (enabled, not in active use):\n- YAML-based multi-step orchestration\n- Syntax: task dependencies, conditional routing, parallel execution\n- **Nuzantara**: loaded but no workflows observed in logs\n\n### Subagents\n\n**Subagent Pattern**: supported via agent routing (`bindings[]` match rules)\n- **Nuzantara**: 2 agents defined (main, coder); no inter-agent delegation observed\n- **Limitation**: agents are isolated; no direct parent-child RPC (agents are standalone)\n\n### Cron / Scheduled Jobs\n\n**Cron Tool**:\n- API: `POST /gateway/cron` or `openclaw cron add <schedule> <command>`\n- Max 24 jobs per gateway\n- **Nuzantara Status**: 0 active jobs logged (scheduler may be frozen since Apr 30 per audit notes)\n\n### Hooks\n\n**7 Lifecycle Hooks** (claude-mem):\n- SessionStart, UserPromptSubmit, PostToolUse, Summary, SessionEnd, PreToolUse, Stop\n- **Nuzantara Use**: memory-core hooks active (observation capture, summary generation)\n\n### Plugin Development\n\n**Plugin Template**:\n- Entry point: `plugin/index.ts` or `dist/index.js`\n- Hooks: export `hooks: { SessionStart, UserPromptSubmit, ... }`\n- MCP Tools: export `tools: [ ... ]` (JSON-RPC 2.0 interface)\n- **Nuzantara Custom Skills**: loaded from `/Users/nuzantara/Desktop/nuzantara/apps/nuzantara-mcp/skills/` (no plugins observed)\n\n### Embedded Agent Runtime\n\n**Pi Agent** (embedded, not delegated):\n- Runs in-process with gateway (RPC loopback)\n- Session state: maintained in gateway memory (not persistent across restarts without memory plugin)\n- Tool dispatch: streaming responses back to gateway → channel output\n\n---\n\n## C. What's NEW (Recent OpenClaw Releases)\n\n| Release | Date | Highlights |\n|---------|------|-----------|\n| **v2026.4.29** | Apr 30, 2026 | Stability improvements, auth profile migration docs |\n| **v2026.4.09** | Apr 9, 2026 | Knowledge Agents system (6 new MCP tools: build_corpus, prime_corpus, query_corpus, etc.) |\n| **v2026.3.31** | Mar 31, 2026 | **[INSTALLED]** DM pairing default, Telegram net timeout handling, provider enum changes |\n| **v2026.1.5** | Jan 5, 2026 | Image model config, agent.imageModel + fallbacks, model shorthands (opus, sonnet, gpt, gemini) |\n\n**Most Notable for Nuzantara**:\n- **Knowledge Agents** (v2026.4.09): Compile filtered corpus from claude-mem observations, query conversationally. 6 new MCP tools (build_corpus, list_corpora, prime_corpus, query_corpus, rebuild_corpus, reprime_corpus). **Not yet exploited.**\n- **Auth Profile Migration** (v2026.3.31 → v2026.4.29): DM pairing now default (requires approval codes); legacy \"open to all\" requires explicit dmPolicy=open + allowFrom=[\"*\"]. **Nuzantara already configured.**\n- **Telegram Timeout Hardening** (v2026.3.31): Retry + backoff for network errors (30s+ waits masked). **Experienced but handled gracefully.**\n\n**Claude-Mem Integration** (v12.1.0, installed via marketplace):\n- Knowledge agents now supported (native corpus build, prime, query MCP tools)\n- Smart-explore extended to 24 languages\n- File-read decision gate (PreToolUse hook blocks redundant reads using observation timeline)\n\n---\n\n## D. Comparison vs Alternatives\n\n| Dimension | OpenClaw | cron-agent-python (Nuzantara) | LangChain/LangGraph | Anthropic Agent SDK (direct) |\n|-----------|----------|------|-----------|---------|\n| **Primary UX** | Gateway + multi-channel | Python cron + custom CLI | Chain/graph DSL | Messages API |\n| **Multi-LLM** | Native (fallback chains) | Manual (explicit per-agent config) | LLMChain abstraction | No native support |\n| **Persistent Memory** | Plugin-based (memory-core) | NotebookLM (external) | No built-in | No built-in |\n| **Channel Binding** | 23+ integrations (Telegram, Discord, etc.) | CLI-only / webhooks | None (user's responsibility) | None |\n| **Workflow Orchestration** | Lobster DSL | Python task queue | LangGraph (DAG-based) | Claude Agent SDK (new) |\n| **Tool Streaming** | Yes (block streaming) | Manual | Yes (via tool classes) | Yes (native) |\n| **Sandbox** | Exec approval socket | None (direct subprocess) | None | None (external runner) |\n| **State Persistence** | SQLite (via plugins) | Disk-backed (JSON/state files) | Not built-in | Not built-in |\n| **Scaling** | Single gateway (local) | Multi-machine (cron dispatch) | App-level (doesn't scale infra) | Delegated to cloud provider |\n| **Ease of Setup** | `openclaw onboard` (90s) | Python venv + config | npm install + boilerplate | anthropic SDK (Python/JS) |\n\n**OpenClaw's Unique Value Propositions**:\n1. **Multi-channel inbox**: Single control plane for Telegram, WhatsApp, Discord, Slack, iMessage, IRC, Teams, Signal, etc.\n2. **Persistence out-of-the-box**: memory-core plugin captures observations + injects into future sessions (no manual logging)\n3. **Native fallback chains**: multi-model routing with per-provider cooldowns + auth management\n4. **Embedded + local**: runs on your machine (no cloud), binds to loopback only (no public expose by default)\n\n**Where OpenClaw Loses**:\n1. **No cloud sync**: single-machine deployment (no multi-region HA out of the box)\n2. **Provider enum rigidity**: only supports explicit providers (openrouter, deepseek, ollama, anthropic); no generic OpenAI-compatible override until v2026.3.31+ (baseUrl interpolation)\n3. **Command limit (Telegram)**: max 100 commands registered; Nuzantara hitting 92-97, dropping 19-20 on each sync\n4. **Scheduler frozen** (apr 30+): cron jobs not running (24-job queue inert); cause unknown\n\n**vs cron-agent-python** (Nuzantara parallel):\n- cron-agent-python: 19 active strategies, each runs independently on schedule; state decoupled (disk-backed JSON)\n- OpenClaw: single agent with multi-LLM routing; state unified in memory-core\n- **Recommendation**: cron-agent-python excels for **independent, scheduled tasks** (classification, analysis per-document); OpenClaw excels for **interactive, multi-turn conversations** with memory (Telegram chatbot + persistent context)\n\n---\n\n## E. Scaling Characteristics\n\n### Concurrency\n\n**Max Concurrent Agents**: 1 gateway, N agents (in Nuzantara: 2)\n- **Per-Agent Sessions**: Unbounded (session state pruned on demand)\n- **Concurrent Requests**: Limited by LLM provider rate limits (OpenRouter: ~100 req/min; DeepSeek: API doc unclear; Ollama: local, unbounded)\n- **Telegram Message Queue**: Sequential (one message processed at a time, 60s timeout → retry → backoff)\n\n### Memory Footprint\n\n| Component | RSS (Idle) | RSS (Active) | Notes |\n|-----------|-----------|-------------|-------|\n| Gateway process | ~200–300 MB | ~400–600 MB | Node.js runtime + channel adapters |\n| memory-core SQLite | ~10 MB | ~50+ MB | Depends on observation count + vector index |\n| Chroma (if enabled) | N/A | ~200+ MB | Python subprocess (uv-managed), not active in Nuzantara |\n| Total (Nuzantara) | ~250 MB | ~500+ MB | Measured via LaunchAgent memory monitor |\n\n### Latency Overhead\n\n| Operation | Latency | Notes |\n|-----------|---------|-------|\n| Gateway routing (inbound message) | <10ms | WebSocket demux + binding match |\n| Agent dispatch (to LLM) | <50ms | HTTP to OpenRouter/DeepSeek |\n| LLM request | 500ms–5s | Depends on model, fallback chain depth |\n| Response streaming (Telegram) | 1–30s | Tool execution + LLM generation + retry backoff |\n| Memory injection (PreToolUse) | 100–500ms | SQLite query + compression (if observation reuse) |\n\n**Gateway overhead is negligible** (<10% of E2E latency).\n\n### State Persistence\n\n**Durable Across Crashes**: Yes (if memory-core enabled)\n- Session state saved to SQLite after each tool_use hook\n- Observation timeline reconstructed on SessionStart\n\n**Graceful Shutdown**: LaunchAgent KeepAlive policy\n- monitored by `launchctl unload/load` (manual) or cron watchdog (Nuzantara)\n- Timeout: 30s (hard kill if not responsive)\n\n### Crash Recovery\n\n**KeepAlive=true** (Nuzantara config):\n- LaunchAgent auto-restarts gateway on exit (non-zero exit code)\n- State surviving: memory-core observations (durable), in-flight messages (lost, retried by Telegram)\n- **Observed**: gateway crashes not logged; LaunchAgent restarts appear transparent\n\n### Multi-Instance Topology\n\n**Federation**: Not supported natively\n- **Workaround**: run multiple gateways on different ports (18789, 18790, ...), but agents are isolated per gateway\n- **Nuzantara**: single gateway (port 18789); no multi-instance setup\n\n---\n\n## F. Security Model\n\n### Loopback-Only Binding\n\n**gateway.bind=loopback** (Nuzantara default):\n- Gateway listens on 127.0.0.1:18789 (localhost only)\n- No public internet exposure (requires SSH tunnel or Tailscale to access from remote)\n- **Threat Model**: protects against direct internet attacks; assumes local machine is secure\n\n### Auth Token & Rate Limiting\n\n**Token** (gateway.auth.token):\n- Long random string (example: 64 char base64)\n- Required in WebSocket `?token=...` query param or HTTP `Authorization: Bearer <token>` header\n- **Storage**: plaintext in `~/.openclaw/openclaw.json` (same permissions as SQLite DB)\n- **Rotation**: manual edit + `openclaw reload` (no auto-rotation tool visible)\n\n**Rate Limiting**:\n- **maxAttempts**: 10 failures in 60s window (Nuzantara config)\n- **lockoutMs**: 300s (5 min) lockout after threshold\n- **Scope**: per-IP (loopback is single IP, so affects all local clients equally)\n\n### exec-approvals.sock\n\n**Manual Approval Flow**:\n- Unsafe exec commands → `exec-approvals.sock` (Unix domain socket, `/tmp/exec-approvals-<pid>.sock`)\n- User approval via CLI: `echo \"approve <exec-id>\" | nc -U /tmp/exec-approvals-<pid>.sock`\n- **Nuzantara Status**: sandbox=off for both agents, so approval flow never triggered\n\n### Sandbox Modes\n\n| Mode | Isolation | Use Case |\n|------|-----------|----------|\n| **off** | None | Development, trusted local use |\n| **non-main** | Per-agent container | Multi-agent isolation (default agents.defaults.sandbox.mode) |\n| **full** | Per-session container | Maximum isolation (experimental) |\n\n**Nuzantara**: mode=off (no isolation). Rationale: single user, local machine, trusted workflows. Trade-off: agents can interfere (shared filesystem, process space).\n\n### Safety Bins Allowlist\n\n**Tools.exec.safeBins**:\n```\nls, cat, tail, which, nuzantara-ops, mcporter\n```\n- Only these binaries bypass approval flow\n- Others require exec approval (if sandbox=non-main or full)\n- **Known Issue** (Mar 22): safeBins not matching plugin config; resolved via plugin reload\n\n**Attack Surface**: agent can only run safe binaries; can't execute arbitrary commands (unless sandbox=off + agent has write access to filesystem, which it does in Nuzantara)\n\n### Plugin Trust Model\n\n**Plugin Loading** (`plugins.allow[]`):\n- Whitelist-based: only plugins in allow-list are loaded\n- Nuzantara loads: memory-core, lobster, llm-task, voice-call (implicit)\n- claude-mem: loaded from `~/.openclaw/extensions/claude-mem/` (manual install, not in core plugins.allow)\n\n**Trust Signals**:\n- Official plugins: signed releases, open-source GitHub\n- User plugins (Nuzantara custom skills): loaded from `/Desktop/nuzantara/apps/nuzantara-mcp/skills/` (same machine, implicit trust)\n- **Warning**: claude-mem flagged as \"loaded without install/load-path provenance\" → suggests side-load outside normal package path\n\n### Secret Handling\n\n**API Key Interpolation**:\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"${OPENROUTER_API_KEY}\"\n }\n }\n}\n```\n\n**Resolution**:\n1. Check environment variable (shellEnv=true in Nuzantara config, shell timeout 15s)\n2. Check EnvironmentVariables from LaunchAgent plist (if running as daemon)\n3. Fall back to plaintext in config (NOT recommended)\n\n**Nuzantara Config**:\n- OPENROUTER_API_KEY, DEEPSEEK_API_KEY, GOOGLE_PLACES_API_KEY, NOTION_API_KEY → in `~/.openclaw/.env` (not shown, but inferred from skills.env)\n- **Risk**: if `.env` checked into git, keys exposed\n\n---\n\n## G. Operational Model\n\n### LaunchAgent Management\n\n**Service File**: `~/Library/LaunchAgents/openclaw.plist` (macOS)\n- **Label**: com.openclaw.daemon\n- **Program**: node (bundled in ~/.openclaw/tools/node-v22.22.0/bin/node)\n- **KeepAlive**: true (auto-restart on exit)\n- **ThrottleInterval**: 30s (min time between restarts after crash)\n- **RunAtLoad**: true (start on login)\n\n**Manual Control**:\n```bash\nlaunchctl load ~/Library/LaunchAgents/openclaw.plist\nlaunchctl unload ~/Library/LaunchAgents/openclaw.plist\nlaunchctl start com.openclaw.daemon\nlaunchctl stop com.openclaw.daemon\n```\n\n**Nuzantara Monitoring**: cron job `monitor-air.log` (implied by logs; monitors for crashes + auto-restart failures)\n\n### Logs\n\n| Log | Path | Rotation | Notes |\n|-----|------|----------|-------|\n| **gateway.log** | `~/.openclaw/logs/gateway.log` | Yes (daily) | Main diagnostic output (diagnostic, channel, agent events) |\n| **gateway.err.log** | `~/.openclaw/logs/gateway.err.log` | Yes (daily) | Errors, warnings, stack traces |\n| **commands.log** | `~/.openclaw/logs/commands.log` | N/A | Slash command executions |\n| **config-audit.jsonl** | `~/.openclaw/logs/config-audit.jsonl` | Append | Config change audit trail |\n\n**Log Level**: `logging.level=info` (Nuzantara config); controlled via `openclaw config set logging.level=debug` (or restart with env var)\n\n**Retention**: no explicit TTL in config; logs grow unbounded (gateway.log: 21.7 GB as of May 2, gateway.err.log: 288 MB). **Risk**: disk space exhaustion.\n\n### Health Endpoint\n\n**Endpoint**: `GET /healthz` (Gateway)\n- **Response**: `{ \"status\": \"ok\" }` (200 OK) or 500 on error\n- **Nuzantara Use**: implied by monitor-air; likely polled every 5–60s\n\n### Metrics Export\n\n**Prometheus**: Not built-in to OpenClaw (as of v2026.3.31)\n- **Workaround**: parse logs with regex + ship to external metrics service\n- **Nuzantara**: no custom metrics exporter observed\n\n### Debugging\n\n**Verbose Mode**: `openclaw gateway --verbose` (CLI flag)\n**Log Level Override**: `OPENCLAW_LOG_LEVEL=debug` (env var at startup)\n**RPC Tracing**: gateway logs all RPC calls (agent → channel) with stack traces on failure\n\n**Trace an Agent Decision**:\n1. Enable debug logging\n2. Send message via Telegram\n3. Check gateway.log for SessionStart → UserPromptSubmit → tool_use → agent response flow\n4. Correlate with memory-core observations (check `.openclaw/agents/main/agent/memory.db` if needed)\n\n### Update Process\n\n**Manual Update**:\n```bash\nnpm install -g openclaw@latest\nopenclaw onboard --update # or --install-daemon to refresh daemon\n```\n\n**Safe Update (Nuzantara)**:\n1. `launchctl stop com.openclaw.daemon` (halt gateway)\n2. Backup `~/.openclaw/openclaw.json` + `~/.openclaw/workspace/`\n3. `npm install -g openclaw@latest`\n4. Review CHANGELOG for breaking changes\n5. Run `openclaw doctor` (auto-migrate config if needed)\n6. `launchctl start com.openclaw.daemon` (restart)\n\n**Auto-Update**: Not configurable in v2026.3.31; manual only.\n\n---\n\n## H. Known Issues & Pitfalls\n\n### 1. Provider Enum Rigidity\n\n**Issue**: openai-completions API wrapper only recognizes explicit `api: \"openai\"` (no generic override)\n\n**Impact**: Can't use arbitrary OpenAI-compatible backends (e.g., vLLM, LocalAI) without forking\n\n**Workaround** (Nuzantara): Use `api: \"openai-completions\"` with openrouter shim (all models exposed via openrouter baseURL)\n\n**Status**: Likely fixed in v2026.4.29 (baseUrl interpolation mentioned in changelog), but not tested against Nuzantara's installed v2026.3.31\n\n### 2. Secret Interpolation (`${VAR}` Only in env)\n\n**Issue**: `apiKey: \"${VAR}\"` resolves ONLY if VAR is in EnvironmentVariables (from LaunchAgent plist or shell env at startup), NOT from `.env` file or inline plaintext\n\n**Impact**: Easy to forget to export env var → silent fallback to missing key → auth failures\n\n**Example** (Nuzantara):\n```json\n{\n \"openrouter\": {\n \"apiKey\": \"${OPENROUTER_API_KEY}\" // resolves to env var if set, else null\n }\n}\n```\n\n**Workaround**: Explicitly set in LaunchAgent plist `EnvironmentVariables` section or `source ~/.openclaw/.env` before `launchctl load`\n\n### 3. mcporter Allowlist Quirks\n\n**Issue** (Mar 22 audit log): safeBins entries `ls, cat, tail, which, nuzantara-ops, mcporter` not matching plugin config → mcporter tool calls rejected\n\n**Root Cause**: Plugin loading race condition (safeBins checked before plugin registration completes)\n\n**Status**: Resolved in Nuzantara by manual reload (launchctl stop/start)\n\n**Fix Expected**: v2026.4.29+ (not tested)\n\n### 4. Plugin Trust Warnings\n\n**Issue**: claude-mem loaded from `~/.openclaw/extensions/claude-mem/` without install/load-path provenance\n\n**Impact**: Minor (code review recommended for untrusted sources); claude-mem is open-source + widely used\n\n### 5. Telegram Network Timeouts\n\n**Issue**: `getUpdates` request times out after 30s; retry backoff (5s → 60s) masks latency but creates gaps in message delivery (Apr 30 + May 2 logs show repeated timeouts)\n\n**Impact**: Inbound messages may be delayed 30–120s during network flaps\n\n**Cause**: Likely ISP or Telegram API throttling (Nuzantara in Bali, geographically distant from Telegram servers)\n\n**Workaround**: Increase timeout (Telegram: `timeoutSeconds=120`) or use webhook polling (if supported in next version)\n\n**Status**: Retry logic + backoff now in v2026.3.31; gracefully handled but not ideal UX\n\n### 6. BOT_COMMANDS_TOO_MUCH (Telegram API Limit)\n\n**Issue**: Telegram API limits /command menu to 100 entries; Nuzantara registering 92–97 commands (skills + custom), dropping 19–20 on each sync\n\n**Impact**: Some skills unavailable in Telegram /command autocomplete menu (but still callable via message mention)\n\n**Log Evidence**:\n```\n[telegram] rejected 92 commands (BOT_COMMANDS_TOO_MUCH); retrying with 73.\n[telegram] accepted 73 commands after BOT_COMMANDS_TOO_MUCH (started with 92; omitted 19).\n```\n\n**Root Cause**: Too many skills enabled (goplaces, xurl, voice-call, notion, antigravity) + OpenClaw bundled commands\n\n**Workaround**: Disable low-use skills in `skills.entries` (set enabled=false for unused ones)\n\n**Fix**: None in OpenClaw core (Telegram API limit). Requires operator intervention.\n\n### 7. Scheduler Frozen (Apr 30+)\n\n**Issue**: Cron jobs not running; 24-job queue inert\n\n**Evidence**: No cron logs in gateway.log since Apr 30; cron tool still responds to queries but doesn't execute\n\n**Impact**: Scheduled tasks (batch processing, daily summaries) missed\n\n**Likely Cause**: \n- Scheduler process crash (separate thread)\n- Job queue lock contention\n- State corruption after config reload\n\n**Status**: Unknown (no debugging done); requires `openclaw doctor` + manual job purge/recreate\n\n**Workaround**: Migrate to external cron runner (separate Python process with its own scheduler) or upgrade to v2026.4.29+\n\n### 8. Context Compaction False Positives\n\n**Issue**: context pruning + compaction may discard relevant observations if TTL expires before session end\n\n**Config** (Nuzantara):\n```\ncontextPruning.mode=cache-ttl, ttl=1h\ncompaction.mode=safeguard, reserveTokensFloor=96k\n```\n\n**Impact**: Multi-day sessions lose early context after 1h, even if still relevant\n\n**Workaround**: Increase TTL to 24h or use `mode: \"never\"` (disables pruning, risks context explosion)\n\n---\n\n## I. Roadmap & Future Direction\n\n**Public Roadmap**: https://github.com/openclaw/openclaw/issues (GitHub Issues, no official roadmap doc)\n\n**Recent PR Signals** (inferred from changelog):\n- **Knowledge Agents** (v2026.4.09): Building queryable \"brains\" from observation history (corpus build + prime + query)\n- **Auth Profile System** (v2026.3.31+): Multi-profile support + role-based failover (not fully enabled in Nuzantara)\n- **DM Pairing Security**: Default dmPolicy=pairing (require approval code for unknown senders) — security-first direction\n- **Provider Enum Expansion**: Support for more providers + generic OpenAI-compatible override (v2026.4.29 changelog hints)\n\n**Likely Future Work** (speculative):\n1. **Cloud Sync**: Multi-region HA + state replication (not in current roadmap, but enterprise feature request)\n2. **Structured Output**: Typed tool responses (Zod schema validation) — currently working, likely formalization\n3. **Voice Wake Improvements**: More language support, custom wake words (v2026.3.31 has voice-call, room for improvement)\n4. **Scheduler Stability**: Fix cron job queue race conditions (based on Apr 30 frozen state)\n5. **Knowledge Agent UI**: Web viewer for corpus browsing + semantic search (claude-mem v12.1.0 foundation)\n\n---\n\n## Summary Table: What Nuzantara Is Using vs. Available\n\n| Feature | Available | Enabled | Status |\n|---------|-----------|---------|--------|\n| **Multi-LLM Routing** | Yes (4 providers) | Yes (fallback chain) | Working, no issues |\n| **Persistent Memory** | Yes (memory-core) | Yes | Working, observations injected |\n| **Telegram Channel** | Yes | Yes | Working, but network timeouts every 30s+ |\n| **Workflow Orchestration** | Yes (Lobster) | Enabled but unused | Ready to use, no barriers |\n| **Knowledge Agents** | Yes (new in v12.1.0) | No | **NOT EXPLOITED** (v2026.4.09 feature) |\n| **Voice-Call Integration** | Yes | Yes | Enabled, not actively tested |\n| **Browser Automation** | Yes (main agent denied) | Partial (coder agent) | Available for coder agent |\n| **Cron Scheduler** | Yes (24 job limit) | Yes but frozen | **BROKEN** since Apr 30 |\n| **Custom Skills** | Yes (extraDirs) | Partially | `/nuzantara-mcp/skills/` not fully synced |\n| **Canvas (macOS)** | Yes | Implicit | Available if using macOS |\n| **Multi-Channel** | Yes (23 channels) | Only Telegram | Others disabled; can be enabled |\n\n---\n\n## Recommendations for Nuzantara\n\n1. **Upgrade to v2026.4.29** (from v2026.3.31): Knowledge Agents system ready; cron scheduler likely fixed; auth profiles stabilized\n2. **Exploit Knowledge Agents**: Build corpus from claude-mem observations; enable conversational history replay (query_corpus tool)\n3. **Fix Cron Scheduler**: Debug Apr 30 freeze; if unresolved in v2026.4.29, fallback to external cron-agent-python runner\n4. **Reduce Telegram Commands**: Disable unused skills (elite-longterm-memory, bluebubbles, discord, slack, spotify, trello) to stay under 100-command limit\n5. **Increase Telegram Timeout**: Raise `timeoutSeconds=120` to mask network latency (or implement webhook polling in next OpenClaw version)\n6. **Monitor Memory Growth**: Track `~/.openclaw/logs/gateway.log` size (currently 21.7 GB); implement log rotation or external log shipping\n7. **Test Voice-Call Skill**: Verify Twilio integration if voice interaction is planned\n8. **Sync Custom Skills**: Ensure `/nuzantara-mcp/skills/` fully registered with OpenClaw (check skills.entries for all custom entries)\n\n---\n\n## Files Referenced\n\n- **Config**: `/Users/nuzantara/.openclaw/openclaw.json` (v2026.3.31 schema)\n- **Installation**: `/Users/nuzantara/.openclaw/lib/node_modules/openclaw/`\n- **Logs**: `~/.openclaw/logs/gateway.log`, `gateway.err.log`\n- **Memory DB**: `~/.openclaw/agents/main/agent/memory.db` (SQLite, not visible in config)\n- **Workspace**: `~/.openclaw/workspace/` (markdown docs + agent state)\n- **Extensions**: `~/.openclaw/extensions/claude-mem/` (installed plugin)\n- **GitHub**: https://github.com/openclaw/openclaw (releases, issues, docs)\n- **Documentation**: https://docs.openclaw.ai (official, updated for v2026.4.29)\n- **claude-mem Marketplace**: `/Users/nuzantara/.claude/plugins/marketplaces/thedotmack/` (v12.1.0, AGPL-3.0)\n\n---\n\n**Document Compiled**: 2026-05-02 13:20 UTC | **Last Config Change**: 2026-05-02 13:20 UTC (Nuzantara-reported version)\n"}}}}