Architecture
Design Principle: AcaClaw is a distribution, not a fork. Every customization lives in OpenClaw’s extension points — skills, plugins, configuration, and environment. Zero source code modifications.
Design Philosophy
Target Users
AcaClaw is designed for scientists who are not software engineers: chemists, physicists, biologists, medical researchers, and students. Every design decision must pass this test: “Would a biology grad student who has never opened a terminal be able to use this?”
The Ubuntu Analogy
| Linux Ecosystem | AcaClaw Ecosystem |
|---|---|
| Linux Kernel | OpenClaw (gateway, agent, CLI, plugin SDK) |
| Ubuntu Desktop | AcaClaw (curated distribution + GUI) |
| apt packages | ClawHub skills + AcaClaw skills |
| apt dependency resolution | AcaClaw environment compatibility testing |
| Ubuntu Security (AppArmor) | AcaClaw security plugin + sandbox-by-default |
| Ubuntu LTS | AcaClaw compatibility-tested OpenClaw versions |
Core Principles
- Non-invasive — Never modify OpenClaw source code. Work through skills, plugins, config, and environments.
- One best — For each capability, ship exactly one tool — the best one. Pre-configured. Works out of the box.
- Data is sacred — Every file modification is preceded by automatic backup. No exceptions.
- Zero-knowledge UX — Users should never encounter “install X dependency” or “run this command”.
- Layered independence — AcaClaw sits ON TOP of OpenClaw, never below. OpenClaw can be upgraded independently.
- Security-first — Stricter defaults than upstream. Workspace-restricted by default.
- Contribute, don’t diverge — Every skill is published to ClawHub. We never maintain a parallel ecosystem.
- Environment compatibility — Every pre-shipped skill is tested together in a single curated environment.
- Don’t re-implement — Never re-implement what OpenClaw already provides. Use it, display it, configure it through OpenClaw’s APIs.
Responsibility Boundary
AcaClaw is a distribution layer — it builds on top of OpenClaw, not alongside it. The following table defines what each layer owns:
| Responsibility | Owner | AcaClaw’s Role |
|---|---|---|
| LLM handling (model routing, streaming, tool calls) | OpenClaw | Use as-is — never re-implement |
| API key storage | OpenClaw config (~/.openclaw/openclaw.json) |
Read and display; write via config.set key/value |
| Model discovery (provider catalogs, model lists) | OpenClaw extensions | Query via models.list — never maintain a separate catalog |
| Provider URLs and auth | OpenClaw extensions | Never hardcode — OpenClaw resolves these automatically |
See Providers & Models for the full provider architecture, model mapping, API reference, and AcaClaw GUI integration method.
| Chat, sessions, message history | OpenClaw gateway | Use via WebSocket RPC — see Chat Handling |
| Plugin SDK, skill system, CLI | OpenClaw | Use as-is |
| Web GUI | AcaClaw | AcaClaw’s own research-focused UI |
| Workspace and project system | AcaClaw plugin | AcaClaw value-add |
| Security policies | AcaClaw plugin | Stricter defaults than OpenClaw |
| Data backup | AcaClaw plugin | AcaClaw value-add |
| Academic skills | AcaClaw + ClawHub | Curated discipline-specific skills |
| Computing environment | AcaClaw | Conda environments for each discipline |
The Golden Rule
If OpenClaw already does it, don’t re-implement it. AcaClaw’s UI and OpenClaw’s UI are both frontends to the same OpenClaw backend. The functionality is implemented once — in OpenClaw. Both UIs just use and display it.
Configuration
AcaClaw writes to OpenClaw’s config using config.get + config.set (WebSocket RPC read-modify-write). The correct way to set a provider API key:
# Via environment variable (recommended for AcaClaw UI)
# AcaClaw writes to config.env so OpenClaw's plugin catalog discovers the key
openclaw config set env.MOONSHOT_API_KEY "sk-..."
# Via CLI (equivalent)
openclaw config set models.providers.openrouter.apiKey "sk-or-..."
# Via shell environment variable
export OPENROUTER_API_KEY="sk-or-..."
AcaClaw’s UI saves API keys to config.env.<ENV_VAR> (not models.providers). OpenClaw’s applyConfigEnvVars copies these into process.env at gateway startup, so the plugin catalog discovers the key and creates the implicit provider config (including base URLs, API type, and model list). This delegates all provider complexity to OpenClaw extensions.
Layer Model
┌─────────────────────────────────────────────────────────────┐
│ Layer 6: AcaClaw Web GUI (design: /en/desktop-gui/) │
│ Research-focused interface — no terminal needed │
├─────────────────────────────────────────────────────────────┤
│ Layer 5: User Workspace │
│ User-installed ClawHub skills, personal data, projects │
├─────────────────────────────────────────────────────────────┤
│ Layer 4: Curated Academic Skills (from ClawHub + bundled) │
│ Installed via clawhub CLI, organized in acaclaw-skills repo │
├─────────────────────────────────────────────────────────────┤
│ Layer 3: AcaClaw Plugins │
│ @acaclaw/workspace, @acaclaw/security, @acaclaw/backup, │
│ @acaclaw/academic-env, @acaclaw/compat-checker │
├─────────────────────────────────────────────────────────────┤
│ Layer 2: AcaClaw Environment │
│ Miniforge + Python + R (opt-in) + Conda envs on demand │
├─────────────────────────────────────────────────────────────┤
│ Layer 1: OpenClaw (Upstream, Unmodified) │
│ Gateway · Agent · Plugin SDK · Skill System · CLI │
├─────────────────────────────────────────────────────────────┤
│ Layer 0: Operating System / Container Runtime │
│ Windows · macOS · Linux │
└─────────────────────────────────────────────────────────────┘
Layer Interaction Rules
| Rule | Description |
|---|---|
| Upward dependency only | Each layer depends only on layers below it |
| No downward coupling | OpenClaw (Layer 1) has no knowledge of AcaClaw |
| Skill precedence | User skills (L5) override curated skills (L4), which override OpenClaw bundled skills |
| Plugin registration | AcaClaw plugins register via the standard OpenClawPluginApi |
| Config overlay | AcaClaw writes to openclaw.json using openclaw config set |
| GUI wraps CLI | The GUI (L6) calls OpenClaw/AcaClaw commands underneath |
Directory Layout
AcaClaw uses two directories at runtime. Each has a clear purpose:
~/.openclaw/ ← OpenClaw directory (config + managed state)
├── openclaw.json ← Single source of truth for ALL config
│ ├── models.providers.* ← API keys, provider auth (OpenClaw handles)
│ ├── agents.* ← Agent definitions, default model (OpenClaw)
│ └── (future) acaclaw.* ← AcaClaw plugin config (via config.set)
├── extensions/ ← Installed OpenClaw extensions
├── skills/ ← Installed skills
├── agents/ ← Agent session data
├── ui/ ← AcaClaw web UI (served by gateway)
├── memory/, logs/, completions/ ← OpenClaw runtime data
└── identity/ ← Gateway identity
~/.acaclaw/ ← AcaClaw runtime DATA only (not config)
├── backups/ ← Versioned file backups (large data)
├── audit/ ← Security audit logs (append-only)
├── config/ ← [MIGRATION PENDING] → openclaw.json
│ ├── plugins.json ← → acaclaw.* in openclaw.json
│ ├── security-mode.txt ← → agents.defaults.sandbox.mode
│ └── setup-pending.json ← → acaclaw.setup.* in openclaw.json
├── gateway.log ← Gateway runtime log
├── start.sh, stop.sh ← Runtime scripts
└── browser-app/ ← Electron/browser app data
Design Principles
| Principle | Rule |
|---|---|
| Config in OpenClaw | All configuration lives in openclaw.json, written via config.set. AcaClaw never maintains a parallel config system. |
| Data in AcaClaw | Large files (backups), append-only logs (audit), and runtime artifacts (scripts, Electron cache) live in ~/.acaclaw/. |
| Shared directory | AcaClaw uses the default ~/.openclaw/ directory. If the user already has a standalone OpenClaw install, AcaClaw inherits its API keys via $include and adds its own config on top. |
| No direct file writes | AcaClaw never writes directly to ~/.openclaw/ — always through OpenClaw’s config.set API or plugin registration. |
Migration Plan
~/.acaclaw/config/ currently holds AcaClaw plugin settings that should migrate into openclaw.json. Until migration is complete:
plugins.jsonsettings will move toacaclaw.*namespace inopenclaw.jsonsecurity-mode.txtwill useagents.defaults.sandbox.modesetup-pending.jsonwill useacaclaw.setup.*namespace- After migration,
~/.acaclaw/config/will be removed ~/.acaclaw/will contain only runtime data: backups, audit logs, gateway log, scripts
The “One Best” Principle
AcaClaw ships one best tool per job, pre-configured and tested together.
Selection Criteria
| Criterion | Weight | Description |
|---|---|---|
| Accuracy / Quality | Critical | Must produce correct, publication-grade results |
| Ease of use (for AI) | High | The AI agent must be able to operate it reliably |
| License | High | MIT/BSD/Apache preferred; GPL/AGPL acceptable as separate process |
| Maintenance | High | Actively maintained, responsive to bugs |
| Size | Medium | Smaller install footprint preferred |
What We Deliberately Exclude
| Excluded | Reason |
|---|---|
| Multiple plotting libraries at install time | One (Matplotlib) is enough; users can add others via ClawHub |
| Deep learning frameworks in base install | Most researchers don’t need them; available as optional profile |
| LaTeX (TeX Live) in base install | ~4 GB; Pandoc handles conversion. Available as optional add-on |
| IDE/editor tools | Scientists don’t need code editors; AcaClaw handles code internally |
Component Architecture
acaclaw/
├── plugins/ # OpenClaw plugins (npm packages)
│ ├── workspace/ # @acaclaw/workspace
│ ├── backup/ # @acaclaw/backup
│ ├── security/ # @acaclaw/security
│ ├── academic-env/ # @acaclaw/academic-env
│ └── compat-checker/ # @acaclaw/compat-checker
│
├── skills.json # Curated skill manifest
├── env/conda/ # Environment definitions
│ ├── environment-base.yml # General academic (acaclaw)
│ ├── environment-bio.yml # Biology (acaclaw-bio)
│ ├── environment-chem.yml # Chemistry (acaclaw-chem)
│ ├── environment-med.yml # Medicine (acaclaw-med)
│ └── environment-phys.yml # Physics (acaclaw-phys)
│
├── config/ # Configuration overlays
│ ├── openclaw-defaults.json # AcaClaw defaults
│ └── openclaw-maximum.json # Maximum security policy
│
├── scripts/
│ ├── install.sh # One-line installer
│ └── uninstall.sh # Uninstaller
│
└── docs/ # Documentation (this site)
Skill Architecture
AcaClaw curates, creates, tests, and publishes high-quality academic skills to ClawHub so the entire OpenClaw community benefits.
Contribute, Don’t Diverge
| What we do | What we don’t do |
|---|---|
| Publish all skills to ClawHub | Mirror skills on our own servers |
| Credit every contributor by name and role | Publish under a team brand without attribution |
| Install skills from ClawHub (official client) | Bypass ClawHub API |
| Test all skills together in one environment | Ship skills with conflicting dependencies |
| File bugs and PRs upstream on OpenClaw | Fork OpenClaw or maintain patches |
Contributor Attribution Model
Every AcaClaw skill includes a Contributors section rendered on the ClawHub skill page:
| Role | Description |
|---|---|
| Creator | Original author who designed and implemented the skill |
| Author | Wrote significant portions of the skill’s functionality |
| Tester | Validated across environments, wrote test cases |
| Maintainer | Keeps the skill updated with new OpenClaw releases |
| Debugger | Fixed critical bugs or edge cases |
| Reviewer | Reviewed code and provided quality feedback |
| Documenter | Wrote usage guides, examples, or translations |
Quality Gates
| Quality gate | What it checks |
|---|---|
| Code review | At least one reviewer signs off |
| Integration tests | Skill runs against pinned OpenClaw version |
| Environment compatibility | Dependencies resolve cleanly in shared Conda env |
| Security review | No exfiltration, no dangerous commands |
| Compatibility test | Works in both Standard and Maximum security modes |
| Attribution check | ## Contributors section present and complete |
Publishing Workflow
1. Contributor opens PR in acaclaw-skills repo
2. AcaClaw team reviews (code, tests, security, compatibility)
3. PR merged → CI publishes to ClawHub under @acaclaw account
4. skills.json updated with new version
5. AcaClaw Hub (acaclaw.com/hub) rebuilt with contributor data
Environment Architecture
Full documentation: Computing Environment
AcaClaw uses Miniforge (conda-forge) to manage Python and R in isolated Conda environments. The design follows three stages:
- Base Install — Miniforge + Python + core scientific stack in a single
acaclawenv - Discipline Selection — Must-have packages for chosen disciplines are merged into the base env. R is opt-in.
- On-Demand Packages — New packages are installed into the default env first. Only on conflict, a new auxiliary env is created and registered.
Environments
| Discipline | Add-on Name | Python Packages | R Packages (opt-in) |
|---|---|---|---|
| Biology | bioclaw | biopython, scikit-bio | r-biocmanager |
| Chemistry | chemclaw | rdkit | — |
| Medicine | medclaw | lifelines, pydicom | r-survival |
| Science/Physics | sciclaw | astropy, lmfit | — |
Environment Compatibility Rules
- One primary environment (
acaclaw) with all disciplines merged — no duplication - R is opt-in — not installed by default
- New packages try the default env first; auxiliary envs created only on conflict
- All envs are registered in
~/.acaclaw/config/env-manifest.jsonand injected into LLM context - Miniforge (conda-forge) handles cross-language dependency resolution between Python and R
- See Computing Environment for the full cascade resolution design
Data Safety Architecture
Full documentation: Data Safety
Research data is irreplaceable. AcaClaw builds a two-layer data protection system on top of OpenClaw’s infrastructure:
| Layer | What it does | Default | Provided by |
|---|---|---|---|
| OpenClaw Infrastructure | Session archiving, config rotation, boundary enforcement, workspace git init, full backup CLI | Always ON | OpenClaw (inherited) |
| Layer A: Per-File Versioning + Trash + Sync | A1: Pre-modification backup (dedup-aware, SHA-256); A2: trash-based deletion; A3: idle-triggered rsync-style sync for manual edits | Always ON | @acaclaw/backup |
| Layer B: Workspace Snapshots | Full .tar.gz snapshots of workspace + config for disaster recovery |
OFF (opt-in) | @acaclaw/backup |
Key Safety Guarantees
| Guarantee | How it works |
|---|---|
| No file modified without backup | before_tool_call hook blocks writes until backup completes (Layer A1) |
| No file permanently deleted | Deletions intercepted and moved to .trash/ with metadata (Layer A2) |
| Backup integrity verified | SHA-256 checksum on backup verified against original |
| Restore always possible | Natural language, LLM tools, or CLI |
| Storage is bounded | Per-layer configurable retention and storage budgets |
| Backups survive crashes | Write-ahead: backup completed before modification begins |
| Git-compatible | AcaClaw backups stored outside git; .gitignore guidance provided |
See Data Safety for the complete design including trash system, workspace snapshots, git compatibility, retention policies, and configuration reference.
UI Strategy: Patched OpenClaw UI vs Separate Plugin UI
The Core Question
AcaClaw needs a research-focused web interface. OpenClaw already ships a web UI (the Control UI). Two approaches:
| Strategy | Summary |
|---|---|
| A. Patch OpenClaw’s UI | Apply light modifications to OpenClaw’s existing Control UI — change theme, remove some tabs, add AcaClaw tabs |
| B. Separate plugin UI (current) | Ship a completely separate SPA, served via registerHttpRoute(), replacing OpenClaw’s UI |
Neither approach modifies OpenClaw’s core source. Strategy A patches the built UI output; Strategy B ignores it entirely.
Strategy A: Patch OpenClaw’s UI
Apply a thin layer of changes on top of OpenClaw’s Control UI: swap the color theme, hide tabs irrelevant to researchers (e.g., developer-facing channel config), add a few AcaClaw-specific tabs (workspace, backup, environment).
What seems attractive:
- Very little code to write — a theme override, a tab filter, a few new route components
- Users get OpenClaw’s existing chat interface, settings, model picker out of the box
- No need to rebuild the entire UI from scratch
What goes wrong:
| Concern | Problem |
|---|---|
| No stable UI extension API | OpenClaw’s Control UI has no theming API, no tab registration system, no plugin slot architecture. “Patching” means directly modifying the built output or monkey-patching the frontend JavaScript at runtime |
| Upstream churn | OpenClaw’s UI changes every release — component structure, CSS class names, route layout, state management. Each OpenClaw update can silently break AcaClaw’s patches. Patches that targeted a specific DOM structure or component name stop working |
| Testing burden | Every OpenClaw release requires retesting all patches. “Did the tab removal still work? Did the theme override break? Did the new tabs still mount correctly?” This is manual integration testing with no contract |
| Fragile coupling | AcaClaw becomes coupled to OpenClaw’s internal UI implementation (component names, CSS selectors, router config, store shapes). None of this is a public API — it can change without notice or deprecation |
| Partial ownership | AcaClaw owns some tabs but not others. Bug reports become ambiguous: is a problem in OpenClaw’s code or AcaClaw’s patches? Debug surface is mixed |
| Upgrade friction | Even though the change is “small,” the user can’t safely run npm update openclaw without checking if AcaClaw’s patches still apply. Version lock-step on the UI layer |
Verdict: Looks cheap, but the maintenance cost is proportional to OpenClaw’s release frequency, not to the size of AcaClaw’s patches. A one-line theme override still breaks when the CSS variable it targets gets renamed.
Strategy B: Separate Plugin UI (Current — Recommended)
AcaClaw ships its own SPA, built independently. The acaclaw-ui plugin registers HTTP routes in the gateway to serve this SPA at /. OpenClaw’s Control UI is disabled by default.
┌─────────────────────────────────────────────────────────┐
│ OpenClaw Gateway (single process, single port :18789) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ WebSocket RPC │ │ REST API │ │ Auth + TLS │ │
│ │ (chat, tools, │ │ (/health, │ │ (device keys, │ │
│ │ sessions) │ │ /v1/models) │ │ challenges) │ │
│ └──────┬───────┘ └──────┬───────┘ └───────┬───────┘ │
│ │ │ │ │
│ ┌──────┴─────────────────┴───────────────────┴───────┐ │
│ │ Plugin HTTP Route Pipeline │ │
│ │ │ │
│ │ acaclaw-ui plugin: │ │
│ │ "/" (exact) → serves AcaClaw SPA index.html │ │
│ │ "/assets/*" → serves built JS/CSS │ │
│ │ "/chat/*" etc. → SPA fallback to index.html │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ OpenClaw Control UI: disabled (gateway.controlUi: false)│
└─────────────────────────────────────────────────────────┘
| Aspect | Assessment |
|---|---|
| Auth | Free. Gateway handles all authentication. Same-origin requests |
| Gateway connection | Free. Same-origin WebSocket, no CORS, no discovery |
| Build independence | AcaClaw builds its own SPA with its own Vite/build config. No dependency on OpenClaw’s UI internals |
| Breakage risk | Low. registerHttpRoute() is a stable plugin SDK API. OpenClaw’s UI refactors don’t affect AcaClaw at all |
| OpenClaw upgrades | Fully independent. npm update openclaw works without retesting AcaClaw’s UI |
| Ownership | Clean. Every pixel is AcaClaw’s responsibility. Bug reports are unambiguous |
| More initial work | Yes — must build chat interface, settings, model picker from scratch. But these are built once against the stable WebSocket RPC API, not against OpenClaw’s internal components |
| Escape hatch | openclaw config set gateway.controlUi.enabled true re-enables OpenClaw’s original UI when needed |
Verdict: More upfront work, but zero ongoing UI maintenance per OpenClaw release.
Head-to-Head
| Concern | Patched OpenClaw UI | Separate plugin UI (current) |
|---|---|---|
| Initial effort | Low (theme + tab changes) | Higher (build SPA from scratch) |
| Maintenance per OpenClaw release | Must verify patches still work | Zero |
| Coupling to OpenClaw UI internals | High (CSS, components, routes) | None |
| Independent upgrades | No (UI patches may break) | Yes |
| Bug ownership | Mixed (OpenClaw + AcaClaw UI) | Clear (all AcaClaw) |
| Relies on stable API | No (internal UI implementation) | Yes (registerHttpRoute()) |
| Customization freedom | Limited to what OpenClaw’s UI allows | Total |
| OpenClaw source modified | No | No |
The key insight: The amount of AcaClaw’s UI code is irrelevant to the maintenance cost. What matters is the stability of the contract you depend on. Patching depends on OpenClaw’s internal UI (unstable, changes every release). The plugin approach depends on
registerHttpRoute()(stable SDK API, versioned).
OpenClaw Control UI Behavior
By default, AcaClaw’s installer sets:
{
"gateway": {
"controlUi": {
"enabled": false
}
}
}
This disables OpenClaw’s built-in UI. AcaClaw’s plugin UI takes over at /. The gateway, RPC, auth, and all backend functionality remain fully operational.
To re-enable for debugging or advanced use:
openclaw config set gateway.controlUi.enabled true
# OpenClaw UI is now available at its base path (default: /openclaw/)
# AcaClaw UI remains at /
Integration Points with OpenClaw
AcaClaw ONLY uses these official OpenClaw APIs:
| Integration point | What AcaClaw uses it for |
|---|---|
OpenClawPluginApi |
Register plugins, tools, hooks, CLI commands |
openclaw.json |
Apply default config (workspace path, security, tool policy) |
| SKILL.md format | Define and install academic skills |
clawhub CLI |
Install skills from ClawHub registry |
openclaw config set |
Set configuration values during install |
openclaw gateway run |
Start the gateway (wrapped by AcaClaw installer) |
| Docker sandbox config | agents.defaults.sandbox.* for Maximum mode |
If OpenClaw doesn’t provide an API for something, AcaClaw Does. Not. Do. It.