Releases: thatsme/AlexClaw
Release list
v0.3.11 — WorkflowRegistry + Convention Fixes
What's New
WorkflowRegistry — Live Run Control
- GenServer + ETS registry tracks every running workflow process in real-time
- Active Runs panel in admin UI — shows current step name, elapsed time, cancel button
- PubSub events (
workflows:runs) drive real-time step-by-step progress updates /runscommand — list active workflows from Telegram/Discord/cancel <run_id>command — stop a running workflow from chat- Crash safety — orphaned "running" DB records auto-marked "failed" via Process.monitor
- Completed runs linger 10s with green status indicator before panel clears
Convention Violations — 195 → 0
- 12 AST-based convention rules enforced across 78 source files
runtime_atom_creation: String.to_atom → String.to_existing_atom (9 errors fixed)missing_spec: ~110 @SPEC annotations added to public functionssingle_value_pipe: ~62 single-step pipes rewritten as direct callstry_rescue_flow_control+silent_rescue: eliminated unsafe patternsprocess_dictionary(18 instances): intentional OTP auth context — suppressed via Giulia- Tests updated for Message
@enforce_keys(:gatewaynow required)
Files Changed
- New:
lib/alex_claw/workflows/registry.ex,test/alex_claw/workflows/registry_test.exs - Modified: executor, dispatcher, workflows context, LiveViews, architecture docs
- 86 files touched for convention fixes
v0.3.9 — Source Consolidation + 2FA-Enforced Skill Management
What's New
Source Consolidation
- LLM split: extracted
LLM.Client— complexity 80→36, god module score 206→111 - Dispatcher split: extracted
SkillCommands,AutomationCommands,AuthCommands— complexity 89→58, 600→280 lines - Gateway hardened: specs, docs, tests added
- Elixir 1.19.5 compatibility: guard restriction fix in Telegram gateway
2FA-Enforced Skill Management
- Mandatory 2FA on all skill load/unload/reload operations — no exceptions
- Admin UI only — skill management removed from Telegram/Discord commands
- Cross-channel verification — Admin UI triggers, Telegram/Discord verifies
- Version bump enforcement — same-version skill loads are rejected
Policy Engine Improvements
- Dynamic config scaffolds per rule type in Admin > Policies
- Help tips (?) on all policy form fields
- TOTP settings seeded in config on first boot
Code Quality
- 116 new tests (689→805)
- 58 new @SPEC annotations (181→239, coverage 46%→61%)
- SkillAPI fully typed — 30 specs on the dynamic skill sandbox API
- Zero unprotected hubs (was 3)
- Heatmap: 5 yellow (all structural), 113 green, 0 red
Discord Gateway
- Message chunking for responses over 2000 characters
Giulia Integration
- Reports folder renamed to
giulia_reports/with branded PDF reports - 4 Giulia bugs caught and fixed during this session (Builds 141-143)
- xref-accurate knowledge graph (AST + BEAM xref)
v0.3.8 — BEAM Clustering
BEAM Clustering: Multi-Node Workflow Distribution
AlexClaw instances can now connect via Erlang distribution and exchange workflow outputs across nodes. Each node runs its own sequential executor independently — no parallel step changes, no shared state complexity.
New Features
- Cross-node workflows —
send_to_workflowandreceive_from_workflowcore skills for inter-node data exchange via:rpc.call(5s default timeout) - ClusterManager GenServer — auto-registration on connect, node monitoring (
:nodeup/:nodedown), remote workflow trigger validation - Cluster admin UI — new page showing connected nodes with status, ping, and management
- Workflow node assignment — "Run on" dropdown: cluster-wide or pinned to a specific node. Scheduler respects assignment.
- Gateway node assignment —
telegram.nodeanddiscord.nodeconfig settings with dropdown UI. Auto-assigns on enable. Single-node mode ignores assignments (backwards compatible). - Cross-node config sync — PubSub broadcasts over BEAM distribution keep ETS caches in sync across nodes
- Global alert bar — warns when gateways are unassigned in cluster mode
- Node identity in nav bar — current node name visible on every page
- Workflow cluster badges —
recv/send/bridgeindicators in workflow list docker-compose_swarm.yml— ready-to-use 2-node cluster for local testingtelegram.enabled— explicit boolean toggle for Telegram gateway (consistent with Discord)
Infrastructure
- Long-name distribution (
alexclaw@nodeN.local) with EPMD bundled in runtime image - 3 new migrations:
cluster_nodes,nodeonworkflow_runs,nodeonworkflows - Default node name
alexclaw@node1.local— same convention single-node and swarm - 33 new tests for cluster code + fixed 20 pre-existing ShellTest failures
Naming Convention
alexclaw@node1.local # single node (default)
alexclaw@node2.local # second node in swarm
alexclaw@nodeN.local # pattern for scaling
Quick Start (Multi-Node)
docker compose -f docker-compose_swarm.yml up --build -d
# node1 on localhost:5001, node2 on localhost:5002Full clustering docs in INSTALLATION.md.
v0.3.7 — Coder Skill, Knowledge Base, Authorization Layer
What's New
Autonomous Skill Generation (Coder)
/codercommand generates dynamic skills from natural language via local LLM- Runtime validation: compile, load, test, retry loop (configurable max retries)
- RAG-powered: queries knowledge base for Erlang/Elixir docs and skill patterns
- Targeted retrieval by kind (erlang_docs, elixir_source, skill_source)
Knowledge Base Reinforcement
- erlang_docs_scraper — fetches OTP docs from GitHub .erl source files with Elixir calling convention hints
- lyse_scraper — scrapes Learn You Some Erlang OTP chapters
- skill_source_indexer — indexes existing skill source code with checksum-based freshness tracking
- elixir_source_scraper — fetches Elixir stdlib source from GitHub
- Knowledge base grew from ~4400 to ~7200 embeddings
Agent Authorization Layer
Three-phase composable authorization system:
Phase 1 — Context-Aware Permission Checks
AuthContextstruct carries caller, type, permission, chain depth, workflow run IDPolicyEngineevaluates context with chain-depth enforcement (max 3)- Structured audit logging for all authorization denials
Phase 2 — Capability Tokens (Macaroon-style)
- HMAC-signed tokens with permission attenuation
- Workflow steps get scoped tokens; cross-skill invocation further restricts
SafeExecutorruns dynamic skills in isolated processes- Tampered tokens rejected via timing-safe comparison
Phase 3 — Policy Rules Engine
- Configurable policy rules stored in PostgreSQL (rate_limit, time_window, chain_restriction, permission_override)
- Per-skill rate limiting via ETS counters
- Audit log persistence with 30-day auto-prune
- Admin UI at
/policiesfor CRUD + audit log viewing
Other Changes
- Removed stale Feeds nav link
- Updated SECURITY.md with full authorization documentation and JSON config examples
v0.3.5 — Shell Skill, Inline Config Editing, Security Hardening
What's New
Shell Skill — Container Introspection
Run whitelisted OS commands (df, free, ps, uptime, git, etc.) inside the container via Telegram /shell or as workflow steps. Protected by 5 layers of defense-in-depth:
- Disabled by default (
shell.enabledin Admin > Config) - 2FA gate when TOTP is enabled
- Whitelist with word-boundary check (configurable via Admin UI)
- Blocklist for shell metacharacters (
|,;,&&,$(, etc.) - No shell interpretation —
System.cmd/3with args as list
Configurable timeout (default 30s) and output truncation (default 4000 chars). git included in runtime Docker image for repo cloning.
Admin Config UX Improvements
- Inline editing — edit settings in-place, no more scrolling to the top of the page
- Collapsed groups by default — all config categories start collapsed, expand what you need
Security Hardening
- Session management improvements (CSRF, body limits)
- Dual enabled-check for shell skill (dispatcher + skill module)
Workflow & Docs
- Container Health Check example workflow in seeds (memory + disk + uptime → LLM summary → Telegram)
- Shell skill scaffolds in workflow editor (Memory, Disk, Processes, Uptime, BEAM node, Git clone)
- Updated README, ALEXCLAW_ARCHITECTURE.md, and SECURITY.md with shell skill documentation
v0.3.4 — Discord Gateway & Health/Metrics
Discord Gateway (issue #1)
Full bidirectional Discord support — use Discord instead of (or alongside) Telegram for all commands and notifications.
- AlexClaw.Gateway.Discord via Nostrum — WebSocket for receiving, REST API for sending
- Configure entirely from Admin > Config — no
.envneeded. Setdiscord.enabled, paste bot token, restart - Auto-detects channel ID on first message (same pattern as Telegram)
- All commands work identically in Telegram and Discord
discord_notifycore skill — deliver workflow output to specific Discord channels viachannel_idconfig- Gateway behaviour abstraction — Router, Behaviour, facade pattern. Skills and Dispatcher are transport-agnostic
See INSTALLATION.md for Discord bot setup instructions.
Health & Metrics Endpoints
GET /health— unauthenticated liveness check (DB ping, version, status). Returns HTTP 503 when DB is unreachable.GET /metrics— authenticated JSON with system stats, LLM provider usage, workflow run counts, skill/circuit breaker states, log severity counts, knowledge/memory entry counts.
Other Changes
Memory.count/1,Workflows.run_stats_today/0query functionsConnCasetest helper for controller tests- SkillAPI: gateway-agnostic
send_message/3,:gateway_sendpermission - 565 tests passing
v0.3.3 — Knowledge Base RAG Pipeline
Knowledge Base RAG Pipeline
Add a documentation-aware RAG (Retrieval-Augmented Generation) pipeline that scrapes Elixir ecosystem documentation, stores it as vector embeddings, and injects relevant docs into chat responses.
New Features
-
Knowledge Base — New
knowledge_entriestable with pgvector 768-dim HNSW index, fully separate from news/conversation memory. Context module with hybrid search: keyword-first term extraction + vector cosine similarity, with keyword results prioritized for precise documentation retrieval. -
HexDocs Scraper Skill — Dynamic skill that discovers modules and guides via ExDoc sidebar JSON, chunks by section/function boundary, deduplicates by source URL, and embeds asynchronously. Currently scrapes 22 packages (4200+ chunks) including full Elixir stdlib and 53 official guides.
-
Chat RAG Integration — Knowledge search injected into chat prompt alongside Memory search. Context source selector in the UI: Docs + Memory / Docs only / Memory only / No context. Doc and memory hit counters displayed per query. System prompt instructs LLM to cite provided documentation over general knowledge.
-
SkillAPI Knowledge Permissions —
knowledge_readandknowledge_writepermissions withknowledge_store,knowledge_search,knowledge_exists?wrappers for dynamic skills.
Fixes
- LLM API Key Resolution —
resolve_api_key/1now falls back from provider record to config settings (llm.gemini_api_key,llm.anthropic_api_key). Providers work correctly when the API key is stored in the config table rather than the provider row.
Packages Scraped
phoenix, phoenix_live_view, phoenix_html, phoenix_pubsub, ecto, ecto_sql, plug, plug_crypto, jason, req, finch, mint, floki, sweet_xml, telemetry, telemetry_metrics, telemetry_poller, bandit, nimble_options, nimble_pool, gen_stage, elixir (stdlib + 53 guides)
Stats
- 13 files changed, 1067 insertions
- 452 tests, 0 failures
- 4243 knowledge chunks embedded with nomic-embed-text-v1.5 (768-dim)
v0.3.0 — Conditional Workflow Branching
What's New
Conditional Workflow Branching
- Skills declare branches — new
routes/0callback on the Skill behaviour. Each skill declares its possible outcomes (e.g.[:on_items, :on_empty, :on_error]) - Triple tuple returns — skills return
{:ok, result, :branch_name}indicating which outcome occurred. Legacy{:ok, result}treated as:on_success - Recursive graph executor — replaces linear
Enum.reduce_whilewith a recursive step walker that follows routes based on branches - Per-step route configuration — workflow editor shows route dropdowns for each branch the skill supports. Target any step or "End workflow"
- Backward compatible — existing workflows with no routes behave identically (linear fall-through, halt on error)
- Loop protection — visited set + max iterations guard prevents infinite cycles
- Default route — fallback route when no branch matches
Skill Routes (all 12 core skills)
| Skill | Branches |
|---|---|
rss_collector |
on_items, on_empty, on_error |
web_search |
on_results, on_no_results, on_timeout, on_error |
web_browse |
on_success, on_not_found, on_timeout, on_error |
api_request |
on_2xx, on_4xx, on_5xx, on_timeout, on_error |
telegram_notify |
on_delivered, on_error |
google_calendar |
on_events, on_empty, on_error |
google_tasks |
on_tasks, on_empty, on_error |
github_security_review |
on_clean, on_findings, on_error |
web_browse |
on_success, on_not_found, on_timeout, on_error |
web_automation |
on_success, on_timeout, on_error |
research |
on_results, on_error |
llm_transform, conversational |
on_success, on_error |
Dynamic Skills Parity
- Routes extracted from module on load, persisted in
dynamic_skillsDB table - Cleaned up on unload, reset on reload
- SkillRegistry ETS extended to 5-tuple:
{name, module, type, permissions, routes} SkillRegistry.get_routes/1returns branches for any skill (core or dynamic)
Circuit Breaker + Branching Integration
- Circuit breaker fires before skill (infrastructure guard)
- Skill branches fire after skill (business logic routing)
- Skip bypasses routes entirely — falls through to next position
- Error routes (
on_error → step N) prevent workflow halt when explicitly configured
UI Improvements
- Route dropdowns per step in workflow editor (edit + add forms)
- Purple route badges on collapsed step view (
on_items→2,on_error→5) - Branch taken shown in workflow run history (purple badge)
Migration
- New
routesJSONB column onworkflow_steps(default:[]) - New
routesarray column ondynamic_skills(default:[])
Example Workflow
Step 1: Fetch RSS feeds (rss_collector)
→ on_items: Step 2 (score and summarize)
→ on_empty: Step 4 (send "no news today")
→ on_error: Step 5 (notify failure)
Step 2: Score via LLM (llm_transform)
→ on_success: Step 3 (deliver to Telegram)
→ on_error: Step 5 (notify failure)
Step 3: Deliver (telegram_notify)
→ on_delivered: End workflow
Step 4: No news (telegram_notify)
→ on_delivered: End workflow
Step 5: Error alert (telegram_notify)
→ on_delivered: End workflow
Zero LLM tokens spent on routing. Pure OTP pattern matching.
v0.2.3 — OTP Circuit Breaker
What's New
OTP Circuit Breaker
- Per-skill circuit breaker — pure OTP implementation using GenServer + ETS, zero external dependencies
- State machine —
:closed(normal) →:open(failing, calls rejected instantly) →:half_open(testing with one probe call) - Auto-recovery — after 3 consecutive failures the circuit opens; after 5 minutes a half-open probe tests if the skill has recovered
- Telegram notifications — alerts on circuit open (with failure count and last error) and circuit closed (recovered)
- Transparent wrapper — skills have zero awareness of the breaker, no changes to
run/1signatures or args - Dynamic skill lifecycle — breakers are cleaned up on skill unload, reset on skill reload (fresh code = fresh circuit)
Workflow Resilience Controls
- Dead letter routing — per-step config for circuit open behavior: halt workflow, skip step (pass input through), or fallback to an alternative skill
- Missing skill handling — per-step config: halt or skip when a skill is not loaded (e.g. dynamic skill unloaded)
- Fallback skill — route to an alternative skill when the primary skill's circuit is open
- All controls are visible dropdowns in the workflow step editor — no JSON editing required
Circuit Breaker Observability
- Dedicated log severity —
:circuit_breakerevents classified by[CircuitBreaker]prefix in log messages - Logs page filter — new "Circuit Breaker" button with blue "CB" badge in the real-time log viewer
UI Improvements
- Tooltips on every field — all workflow and step editor fields now have
?tooltip balloons with contextual help - Extracted reusable
tipcomponent for consistent tooltip rendering across the UI
Testing
broken_skill.extest fixture — always-failing dynamic skill for circuit breaker verification- Unit tests for all state transitions (closed → open → half_open → closed/open)
v0.2.2 — Semantic Memory & Chat
What's New
Semantic Memory with pgvector Embeddings
- Hybrid search — vector cosine similarity + keyword matching, merged and deduplicated
- Async embedding pipeline — all skills auto-embed stored knowledge in the background via TaskSupervisor
- Multi-provider embeddings — Gemini
gemini-embedding-001, Ollamanomic-embed-text, or any OpenAI-compatible endpoint - 768-dimension vectors with HNSW index for fast similarity search
- Batch re-embed —
Memory.reembed_all/1for model switching
Chat Page (Admin UI)
- Interactive conversation with semantic memory context — queries are enriched with relevant memories (CVEs, news, research, past conversations)
- Provider selector — pick any configured LLM (cloud or local) directly from the dropdown
- Conversation history stored back to memory for continuity
- Memory hit counter showing how many memories matched each query
New Dynamic Skills
- NVD CVE Monitor — fetches vulnerabilities from NIST NVD 2.0 JSON API, filters by CVSS severity (HIGH/CRITICAL), stores with embeddings, notifies via Telegram
- RSS v2 enhanced — full article content fetching via Floki HTML parser, configurable timeouts,
dc:datefallback for RDF/RSS 1.0 feeds
Improvements
- Configurable RSS fetch timeout — global setting (
skills.rss.fetch_timeout) + per-step override. Default 15s, adjustable for slow feeds - Embedding config —
embedding.providerandembedding.modelsettings in admin UI - Updated seed feeds: CISA News, The Hacker News, BleepingComputer, Krebs on Security
Fixes
- Fixed Gemini embedding model (
text-embedding-004→gemini-embedding-001withoutputDimensionality: 768) - Fixed CISA RSS feed URLs (old paths returned 404)
- Fixed Ecto sandbox compatibility for async embedding tasks in tests
- Fixed nil guard in
embed_entrywhen memory is deleted before embedding completes
