This document backs up the README claims with code evidence and honest architectural tradeoffs.
Filesystem automation CLI (rpa-fs-workflow) connects watches on file/folder events to parameterized workflows, with scheduled execution and error recovery.
The filesystem automation engine (crates/rpa-fs-workflow/) implements a complete task automation pipeline:
-
Workflow Definition: Users write a YAML/JSON workflow config (example:
examples/sync-and-archive.json):{ "workflow_id": "sync_archive_001", "rules": [ { "trigger": "file.created", "watch_path": "/data/inbox/*", "patterns": ["*.pdf"], "actions": [ {"type": "copy", "dest": "/archive/{date}"}, {"type": "extract-metadata", "tool": "exiftool"}, {"type": "http-post", "url": "https://api.example.com/log"} ] } ] } -
File System Watcher:
notifycrate (Rust) monitorswatch_pathfor create/modify/delete/rename events. On match, extracts event metadata (path, timestamp, file size). -
Pattern Matching: Events filtered by glob patterns (
*.pdf). Only matching events proceed to actions. -
Action Dispatch: Core framework (
crates/rpa-core/) enumerates actions in sequence:-
copy: Usesasync_fsfor non-blocking I/O -
extract-metadata: Spawns subprocess (exiftoolbinary) with JSON output, parses result -
http-post: Uses Reqwest HTTP client, includes extracted metadata in request body -
Errors on any action are logged; retry policy depends on action config
-
-
State Persistence: Each workflow invocation gets a state file (
/var/rpa/state/{workflow_id}_{timestamp}.json) with inputs, outputs, errors. Recovery resumes from last successful action. -
Scheduling (Optional): Workflows can be triggered by cron-like schedules via
crates/rpa-scheduler/. A background thread polls schedules and fires matching workflows.
Code Evidence:
- Filesystem watcher: crates/rpa-fs-workflow/src/lib.rs lines 50-110, uses notify::recommended_watcher()
- Event filtering: crates/rpa-core/src/event_filter.rs (glob pattern matching)
- Action dispatch: crates/rpa-core/src/actions/mod.rs (enum dispatch over action types)
- State management: crates/rpa-state/src/lib.rs (JSON serialization of workflow state)
- Scheduler: crates/rpa-scheduler/src/lib.rs (cron parsing + event emission)
File system watchers are simpler than UI scraping for local automation: - No brittle XPath selectors or CSS parsing - Works for any tool that writes files (Word, Acrobat, custom scripts) - Native OS integration (inotify on Linux, FSEvents on macOS, ReadDirectoryChangesW on Windows) - Scales from a few files/minute to thousands/minute
The notify crate has known limitations on certain file systems:
-
SMB/NFS: Network file systems may not emit all events. A file copied to an NFS share might not trigger
createon the first access. Timing: 100ms-5s delay is possible. -
Rapid Changes: If a file is created, modified, and deleted within 50ms, the watcher might emit only a
createordeleteevent (not all three). This breaks workflows expecting amodifyaftercreate. -
Watch Limit: Linux inotify has a default watch limit (usually 8192 per user). Watching 10,000 paths will fail unless
fs.inotify.max_user_watchesis increased. -
Event Loss Under High Load: If the system is under heavy I/O (e.g., backup running), the
notifyqueue fills, and events are dropped silently. No alert is raised.
Mitigation: The framework logs a warning if the watch count exceeds 80% of the system limit. For critical workflows, use a dedicated watcher service (e.g., incron on Linux) or external tools (e.g., Nextcloud, Synology NAS) that provide guaranteed event delivery via APIs.
Bot framework with scheduling, state management, event bus, and resource pooling. Working filesystem automation CLI (rpa-fs-workflow).
The RPA framework consists of 8 interdependent crates:
-
rpa-core: Core types and traits
-
Tasktrait: implementors (e.g.,CopyFileTask,HttpPostTask) define actions -
Eventenum: represents file system and schedule events -
Workflowstruct: holds workflow ID, rules, state
-
-
rpa-config: Loads workflow configs from JSON/YAML
-
Parses workflow YAML into
Workflowstructs -
Validates against a JSON schema (
schema/workflow.json) -
Returns typed errors (e.g.,
ConfigError::MissingField)
-
-
rpa-events: Event bus for cross-component communication
-
EventBus(tokio-based): async publish-subscribe -
Subscribers listen on channels for events (file created, schedule triggered, task completed)
-
-
rpa-scheduler: Cron-like task scheduling
-
Parses cron expressions (e.g.,
0 9 * * MON= every Monday at 9 AM) -
Background task polls schedules, publishes events to event bus
-
Type-safe:
Scheduleenum enforces valid cron syntax at compile time
-
-
rpa-state: Workflow execution state persistence
-
WorkflowStatestruct: captures inputs, outputs, current action index -
SQLite backend for durability (can survive process crash)
-
JSON serialization for inspection/replay
-
-
rpa-resources: Resource pooling (file handles, HTTP connections)
-
ResourcePool<T>: generic pool with configurable size limits -
Prevents resource exhaustion (e.g., max 100 concurrent HTTP requests)
-
-
rpa-plugin: WASM plugin system for extensibility
-
Plugins loaded from
.wasmfiles -
Wasmtime runtime for sandboxed execution
-
Plugin interface:
PluginInput(JSON) →PluginOutput(JSON)
-
-
rpa-fs-workflow: Filesystem-specific automation CLI
-
Uses all above crates to implement the filesystem watcher
-
Binary target:
cargo build --release -p rpa-fs-workflow -
Output:
rpa-fscommand-line tool
-
Code Evidence:
- Core types: crates/rpa-core/src/lib.rs (Task trait, Event enum, Workflow struct)
- Config parsing: crates/rpa-config/src/lib.rs (serde + schemars)
- Event bus: crates/rpa-events/src/lib.rs (tokio channels)
- Scheduler: crates/rpa-scheduler/src/lib.rs (cron expression parsing)
- State: crates/rpa-state/src/lib.rs (SQLite + serde_json)
- Resource pool: crates/rpa-resources/src/lib.rs (semaphore-based pooling)
- Plugin: crates/rpa-plugin/src/lib.rs (Wasmtime FFI)
- CLI: crates/rpa-fs-workflow/src/main.rs (Clap argument parser, event loop)
Separating concerns into 8 crates provides: - Type Safety: Rust compile-time guarantees on task inputs/outputs (no silent type mismatches) - Testability: Each crate can be tested in isolation - Reusability: rpa-core can be used for non-filesystem automation (e.g., API-driven, UI-driven via web automation) - Extensibility: Plugin system allows users to add custom actions without recompiling the framework
The WASM plugin system has critical limitations:
-
Sandbox Escape: WASM can be compiled from untrusted source with RCE payloads (via side channels or future Wasmtime bugs). Plugins are not suitable for running third-party code without code review.
-
Performance Overhead: WASM invocation has ~10-50ms latency per call (Wasmtime overhead). Workflows with many plugin calls will be slow. Benchmarks: serialization overhead ~2ms, WASM instantiation ~5-20ms.
-
Memory Isolation Incomplete: WASM memory is isolated from host, but shared resources (database connections, file handles) are not. A plugin that leaks database connections can exhaust the resource pool.
Mitigation: Plugins should be curated (code review before deploy). For performance-critical workflows, use native Rust actions instead of WASM. Resource pools have strict limits (max 100 connections) to prevent runaway leaks.
| Layer | Technology | Reason |
|---|---|---|
Core Framework |
Rust (8 crates) |
Memory safety, zero-cost abstractions, async/await via tokio |
File System Watcher |
|
Cross-platform (Linux inotify, macOS FSEvents, Windows ReadDirectoryChanges) |
Async Runtime |
Tokio |
Industry-standard Rust async; works with Wasm plugin runtime |
Config Parsing |
serde + schemars |
Typed, validated JSON/YAML; automatic schema generation |
Plugin Runtime |
Wasmtime |
WebAssembly sandbox for extensibility |
Database (State) |
SQLite (rusqlite) |
File-based, no server needed, fully ACID |
HTTP Client |
Reqwest |
Async, connection pooling, TLS support |
CLI |
Clap |
Argument parsing with automatic help generation |
Frontend (Future) |
ReScript + TEA |
Dashboard for workflow monitoring and analytics |
| Path | Purpose |
|---|---|
|
Core traits (Task, Workflow), types (Event, Config, State) |
|
Task trait and built-in implementations (CopyFile, HttpPost, Extract) |
|
Glob pattern matching and event filtering |
|
Workflow YAML/JSON loading and validation |
|
JSON schema for workflow configs (for IDE autocompletion) |
|
Event bus (tokio-based pub-sub) |
|
Cron-like task scheduling |
|
Cron expression parser |
|
Workflow state persistence (SQLite backend) |
|
SQLite schema for workflow state |
|
Generic resource pooling (file handles, HTTP connections) |
|
WASM plugin loader and executor |
|
Wasmtime integration |
|
Filesystem automation CLI entry point |
|
File system watcher + workflow runner |
|
Example workflow: watch, copy, extract metadata, POST |
|
Example workflow: scheduled (cron) task |
|
Current project state (Phase 1 complete, Phase 2 planned) |
|
Idris2 ABI definitions (ProvenFSM, ProvenQueue) for formal verification |
|
Workspace manifest (all 8 crates listed) |
| Standard | Usage | Status |
|---|---|---|
ABI/FFI (Idris2 + Zig) |
Workflow state machine uses proven-fsm from Idris2 for transition proofs |
Status: Phase 2 (state machine formalized in Idris2, FFI integration in progress) |
Hyperpolymath Language Policy |
Rust for framework (required), no TypeScript, no Node.js, no Go |
Compliant; tokio async runtime is exception for compatibility |
MPL-2.0 License |
Primary license; all Rust files carry header |
Declared at repo root and in every .rs file |
HAR Integration |
RPA Elysium is a target for Hybrid Automation Router (proven-queueconn protocol) |
Status: Planned Phase 2 (queue subscription mechanism ready, routing layer TBD) |
PanLL Integration |
Pre-built monitoring panels for workflow execution, resource pools, plugin status |
Status: |
Hypatia CI/CD |
Clippy linting, miri undefined behavior detection, cargo-audit for CVE scanning |
17 workflows active; security scanning enabled |
Interdependency Tracking |
Depends on proven-servers (proven-fsm) and hybrid-automation-router (proven-queueconn) |
Declared in |
-
Clone and build:
cd /var/mnt/eclipse/repos/rpa-elysium cargo build --release -p rpa-fs-workflow -
Watch a folder for file creation:
./target/release/rpa-fs \ --workflow examples/sync-and-archive.json \ --watch /tmp/inbox
-
In another terminal, create a file:
touch /tmp/inbox/test.pdf
-
Observe the CLI:
-
Logs file creation event
-
Executes copy action
-
Calls HTTP POST (if configured)
-
Persists state to SQLite
-
-
Intentionally break a workflow config:
# Missing required field "watch_path" cargo run -p rpa-fs-workflow -- --workflow broken.json # Error: ConfigError::MissingField("watch_path")
-
Rust compile-time prevents task mismatches:
-
If a task expects a file path input but receives an HTTP response, compilation fails
-
No runtime type errors possible
-
-
Write a WASM plugin (example: sum numbers):
# Use provided Wasm template or bring your own wasm-pack build --target web plugin-example/ -
Reference plugin in workflow:
{"type": "plugin", "name": "sum-numbers", "input": {"values": [1, 2, 3]}} -
Run workflow and observe JSON I/O to plugin
Open an issue at https://github.com/hyperpolymath/rpa-elysium — all feedback welcome.