Skip to main content

Governed agent platform with MandelDB genetic memory. BB4C — Breath Before Code.

Project description

ClawTex

BB4C — Breath Before Code. Every action governed. Every thought remembered. Every agent intentional.

Built by DeVere Cooley · AN2B LLC

ClawTex is the product that should have shipped as OpenClaw — a complete, secure, memory-based agent. Governance first. Real memory, not markdown files.


What Is It?

ClawTex is a production-ready AI agent platform built around four non-negotiable principles:

  1. Governance first — The Warden policy engine gates every tool call before execution. No action happens without a breath.
  2. Real memory — MandelDB provides semantic, vector-backed recall. Not flat files. Not conversation history. Genetic memory.
  3. Identity — Every agent has a SOUL.md. Character is configuration.
  4. Composability — Skills, channels, and tools are modular. Plug in Telegram, Slack, or build your own.

Why?

Most agent frameworks give you:

  • A chat loop
  • Some tools
  • Maybe a system prompt

That's not enough for production. Production agents need:

  • Policy enforcement — you can't ship an agent that might delete emails or send unauthorized messages
  • Persistent memory — users expect agents to remember context across sessions
  • Auditability — you need to know what was blocked, approved, and why
  • Character — a consistent identity that users can trust

ClawTex ships all of this out of the box.


Quickstart

Three commands. That's it.

pip install clawtex

clawtex setup   # interactive wizard — configures everything

clawtex start   # your agent is live

The wizard handles your LLM key, MandelDB memory key, and channel tokens. No manual .env editing. No guesswork.


Getting Your Keys

You need 2 required keys and 1 optional channel token to get started.

🧠 MandelDB API Key (required — your agent's memory)

  1. Go to mandeldb.com
  2. Create a free account
  3. Go to API KeysCreate Bot Key
  4. Copy the key — it starts with ek_bot_

This gives your agent its own private memory namespace. Everything it learns lives here.


🤖 LLM Key — pick one:

Anthropic (Claude) — recommended

  1. Go to console.anthropic.com
  2. Sign up / log in
  3. Go to API KeysCreate Key
  4. Copy the key — it starts with sk-ant-

OpenAI (GPT-4)

  1. Go to platform.openai.com
  2. Sign up / log in
  3. Go to API KeysCreate new secret key
  4. Copy the key — it starts with sk-

💬 Channel Token — pick one (or both):

Telegram

  1. Open Telegram and search for @BotFather
  2. Send /newbot
  3. Follow the prompts — give your bot a name and username
  4. BotFather gives you a token — it looks like 7812345678:AAH...
  5. Start a chat with your bot and send it a message before running ClawTex

Slack

  1. Go to api.slack.com/appsCreate New AppFrom Scratch
  2. Under OAuth & Permissions, add these Bot Token Scopes: chat:write, im:write, channels:read, users:read
  3. Under Socket Mode, enable it and create an App-Level Token — this is your SLACK_APP_TOKEN (starts with xapp-)
  4. Install the app to your workspace → copy the Bot User OAuth Token (starts with xoxb-)
  5. Invite your bot to a channel: /invite @yourbotname

Minimum to get started: MandelDB key + one LLM key. Channel tokens are optional — without one, ClawTex runs in CLI mode (great for testing).


Architecture

┌───────────────────────────────────────────────────────────────┐
│                         ClawTex Agent                          │
│                                                                │
│  Channel                                                       │
│  ┌──────────┐                                                  │
│  │ Telegram │                                                  │
│  │  Slack   │──message──▶  handle_message()                    │
│  │   CLI    │                                                  │
│  │   MCP    │                                                  │
│  └──────────┘                                                  │
│                                                                │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │                      Agent Core Loop                       │  │
│  │                                                            │  │
│  │  1. classify intent     (INSTANT / LIGHT / STANDARD /DEEP) │  │
│  │  2. recall memories     (MandelDB or pgvector)             │  │
│  │  3. build prompt        (SOUL.md + memory + skills)        │  │
│  │  4. call LLM            (Anthropic / OpenAI)               │  │
│  │  5. for each tool call:                                    │  │
│  │        breathe() ─▶  Warden.check_async(ctx)               │  │
│  │                       │                                    │  │
│  │                       ├─ ALLOW  ─▶  execute                │  │
│  │                       ├─ DENY   ─▶  BlockedByWarden        │  │
│  │                       └─ REVIEW ─▶  approval_callback      │  │
│  │                                      │                     │  │
│  │                                      ├─ approved → execute │  │
│  │                                      └─ rejected → block   │  │
│  │  6. redact + ingest exchange  (MemoryContext)              │  │
│  └──────────────────────────────────────────────────────────┘  │
│                                                                │
│  ── Four governance layers ────────────────────────────────    │
│                                                                │
│  Warden              Tool registry       Skill manifests       │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐        │
│  │ policy.yaml  │   │  source-     │   │  declared_   │        │
│  │ rules +      │   │  tracked;    │   │  action_     │        │
│  │ when: ctx    │   │  TRUSTED_    │   │  types       │        │
│  │ NEVER_AUDIT  │   │  TOOL_       │   │  audit vs    │        │
│  │ _BYPASS      │   │  MODULES     │   │  registry    │        │
│  └──────────────┘   └──────────────┘   └──────────────┘        │
│                                                                │
│  Memory redactor (Layer 4)                                     │
│  ┌─────────────────────────────────────────────┐               │
│  │ scrubs API keys + PII before every ingest   │               │
│  │ sk-ant-… → [REDACTED:ANTHROPIC_KEY]         │               │
│  └─────────────────────────────────────────────┘               │
└───────────────────────────────────────────────────────────────┘

See docs/GOVERNANCE.md for the full layer-by-layer walkthrough.


Configuration

All configuration lives in .env (see .env.example):

Core

Variable Required Description
CLAWTEX_NAME Yes Agent name / memory namespace
CLAWTEX_SOUL No Path to SOUL.md (default: ./SOUL.md)
LLM_PROVIDER Yes anthropic or openai
ANTHROPIC_API_KEY If anthropic Your Anthropic API key
OPENAI_API_KEY If openai Your OpenAI API key
ANTHROPIC_MODEL No Override Claude model (default: claude-3-5-sonnet-20241022)
OPENAI_MODEL No Override OpenAI model (default: gpt-4o)

Memory

Variable Required Description
MEMORY_BACKEND No mandeldb (default) or pgvector
CLAWTEX_EIDETIC_URL Yes (MandelDB) MandelDB base URL
CLAWTEX_EIDETIC_KEY Yes (MandelDB) ek_bot_… bot key
CLAWTEX_EIDETIC_GCLOUD_ACCOUNT No gcloud identity token path (Cloud Run)
DREAM_INTERVAL_HOURS No Memory consolidation interval (default: 6)
CLAWTEX_REDACT_DISABLED No 1 to turn off redaction (debug only)
CLAWTEX_REDACT_PII No 1 to also redact emails + long digit runs
CLAWTEX_REDACT_EXTRA No Additional regex for site-specific secret shapes

Legacy MANDELDB_URL / MANDELDB_API_KEY are still accepted for backwards compatibility.

Governance

Variable Required Description
WARDEN_POLICY No Path to policy YAML (default: bundled default.yaml)
WARDEN_MODE No enforce (default) / audit / strict
CLAWTEX_TRUSTED_TOOL_MODULES No Module prefixes allowed to register tools. Prefix with strict: to hard-reject others. Set this in prod.

Channels

Variable Required Description
TELEGRAM_BOT_TOKEN Optional Telegram bot token
SLACK_BOT_TOKEN Optional Slack bot token
SLACK_APP_TOKEN Optional Slack app-level token (Socket Mode)

Governance

Governance in ClawTex is four independent layers — not one policy engine. Each layer closes a different class of failure. Together they make "governed agent" a defensible claim rather than a marketing line.

Layer What it does
Warden Gates every tool call against a policy. ALLOW / REVIEW / DENY.
Tool registry trust Rejects tools registered from untrusted Python modules.
Skill manifests Audits that skills only drive their declared action_types.
Memory redactor Scrubs secrets and optional PII before any memory ingest.

👉 Full walkthrough of every knob: docs/GOVERNANCE.md

Decisions & default policy

# clawtex/governance/policies/default.yaml (v2)
version: 2
default: REVIEW   # unknown action_types pause before acting — BB4C default

rules:
  - action: "file.delete"
    decision: DENY
  - action: "email.delete"
    decision: REVIEW
  - action: "web.search"
    decision: ALLOW
  # …

default: REVIEW is the BB4C posture: anything the policy author didn't anticipate should pause, not proceed. Deployments that prefer ALLOW-by-default must set it explicitly.

Context-aware conditions

Rules can gate on the tool call's arguments — path, URL host, recipient, regex, etc.:

rules:
  - action: "file.write"
    decision: ALLOW
    when:
      input.path:
        glob: ["/tmp/**", "./workspace/**"]
  - action: "file.write"
    decision: REVIEW

  - action: "http.post"
    decision: ALLOW
    when:
      input.url:
        host_suffix: ["an2b.com"]   # api.an2b.com passes, evilan2b.com doesn't
  - action: "http.post"
    decision: REVIEW

Operators: equals, not_equals, in, not_in, glob, regex, host_in, host_suffix. Multiple operators in one when AND together.

Warden modes

Mode Behavior
enforce (default) DENY blocks. REVIEW pauses for approval callback, else blocks.
audit Log but allow — except exec, file.delete, email.delete, db.drop, db.truncate, which always enforce (NEVER_AUDIT_BYPASS).
strict REVIEW is treated as DENY (no human-in-the-loop).

Tool registry trust (CLAWTEX_TRUSTED_TOOL_MODULES)

Any Python package that imports clawtex.tools.registry can register a tool. Without a trust model, a malicious dependency could register exec under action_type="web.search" and bypass Warden entirely. Fix:

# Permissive — warn on untrusted sources (dev)
CLAWTEX_TRUSTED_TOOL_MODULES=clawtex.tools,my_company_tools

# Hard-reject untrusted sources (prod)
CLAWTEX_TRUSTED_TOOL_MODULES=strict:clawtex.tools,my_company_tools

Every production deployment should set this. clawtex check lists each tool's source module and flags any that are untrusted.

Memory redactor

Vector memory is forever. A user pasting an API key should not produce a permanent, recallable artifact. clawtex.memory.redactor runs over every exchange before ingest:

# Input
"my key is sk-ant-AAAABBBBCCCCDDDDEEEEFFFF1234"

# What lands in MandelDB / pgvector
"my key is [REDACTED:ANTHROPIC_KEY]"

Built-in shapes: Anthropic, OpenAI, MandelDB bot keys, GitHub tokens, AWS / Google / Slack keys, JWTs, Bearer tokens, PEM blocks.

CLAWTEX_REDACT_PII=1                    # also scrub emails + long digit runs
CLAWTEX_REDACT_EXTRA=INT-[A-Z0-9]{8}    # your own secret shapes
CLAWTEX_REDACT_DISABLED=1               # DEBUG ONLY — do not set in prod

The breathe() method

# In agent.py — the philosophical core of ClawTex
async def breathe(self, tool: ToolDefinition, tool_input: dict) -> Decision:
    """Pause and consult the Warden before executing any tool call. BB4C."""
    decision = await self.warden.check_async(tool.action_type, context)
    if self.warden.enforce_decision(tool.action_type, decision):
        raise BlockedByWarden(tool.action_type, tool.name)
    return decision

warden.enforce_decision() is the authoritative "should I block?" answer — it encodes mode + NEVER_AUDIT_BYPASS rules in one place so callers can't drift.


Memory

ClawTex runs on two interchangeable memory backends — pick per deployment.

Backend Use when Set MEMORY_BACKEND=
MandelDB (default) You want managed semantic memory + dream consolidation mandeldb
pgvector You're running your own Postgres (e.g. Supabase) and want schema isolation per tenant pgvector

Both present the same interface — MemoryContext.build() / record_exchange() / ingest_fact() — so switching backends is an env-var change, not a code change.

How It Works

# Before every response: recall what's relevant
memories = await memory.recall(query=user_message, top_k=5)

# After every exchange: remember what happened (redacted first)
await memory.record_exchange(user_message=msg, assistant_reply=reply)

# Periodically: consolidate memories (MandelDB only)
await memory.trigger_dream()

Redaction before ingest

Every user_message and assistant_reply passes through clawtex.memory.redactor before being written. Built-in patterns scrub Anthropic / OpenAI / MandelDB / GitHub / AWS / Google / Slack keys, JWTs, Bearer tokens, and PEM blocks. Vector memory is forever; leaked secrets must never become recallable artifacts.

See the Memory redactor section above for config.

🧠 Brain Startup — Blackout Recovery

ClawTex agents auto-reconnect to their memory on every startup. If a session ends (crash, token limit, restart), the agent pulls recent context from the backend the moment it comes back online — no cold starts.

agent = ClawTexAgent(name="MyAgent")
await agent.start()  # ← restores context from MandelDB, injects into system prompt

The startup context is injected before per-message recall, so the agent always knows:

  • What it was working on last session
  • Open threads and pending decisions
  • Recent exchanges

Fail-open — if the memory backend is unreachable, the agent continues without startup context (degraded but functional). Never blocks startup.

Getting a MandelDB Key

python scripts/register_bot.py --name MyAgent

This registers your agent with the MandelDB EngramPort API and writes your ek_bot_ key to .env.

Dream Scheduler

ClawTex runs a background dream scheduler that triggers MandelDB memory consolidation every DREAM_INTERVAL_HOURS (default: 6h). This compresses and clusters memories, improving recall quality over time.


Skills (OpenClaw-compatible)

ClawTex uses the same SKILL.md format as OpenClaw — skills are fully interoperable between both frameworks, plus ClawTex adds optional governance declarations.

👉 Full authoring guide: docs/SKILLS.md

Installing Skills via clawhub

# Install the clawhub registry client (one-time)
npm install -g clawhub

# Install a skill
clawtex skill install weather
clawtex skill install github/issues

# Search for skills
clawtex skill search summarize

# List what's installed
clawtex skill list

# Update all skills
clawtex skill update

# Update a specific skill
clawtex skill update weather

How Skills Work

At startup, ClawTex:

  1. Scans CLAWTEX_SKILLS_DIR (default: ./skills) for subdirectories with SKILL.md
  2. Parses YAML frontmatter from each SKILL.md to extract name, description, version, tags
  3. Injects an <available_skills> block into every system prompt

Per message, ClawTex:

  1. Runs keyword matching against skill descriptions and tags
  2. If a skill matches, injects its full SKILL.md content as <active_skill> in the prompt
  3. The agent follows the skill's instructions for that response

Writing a Skill (OpenClaw-compatible format)

skills/
└── my-skill/
    └── SKILL.md

SKILL.md with YAML frontmatter:

---
name: my-skill
display_name: My Skill
description: What this skill does in one line.
version: 1.0.0
tags: [keyword1, keyword2]
tools: [web_search, file_read]
declared_action_types: [web.search, file.read]
---

## Instructions

Describe what the agent should do when this skill is active.

## Usage

...

---
*A ClawTex skill · BB4C · AN2B LLC*

The description and tags fields drive keyword matching. The declared_action_types field lets clawtex check audit that your skill only drives the action_types you declared — if the skill lists tools: [exec] but only declares web.search, the audit flags it. Opt-in; skills without the field are skipped. Glob patterns like file.* are supported.

ClawTex vs OpenClaw — Skill Differences

Feature OpenClaw ClawTex
SKILL.md format ✓ (identical)
clawhub install
Skill injection System prompt System prompt
Per-message matching Yes Yes
declared_action_types audit
MandelDB / pgvector memory
Warden governance
Tool registry trust model
Secret/PII redaction

Adding Tools

Tools are async Python functions registered with the tool registry:

# my_company_tools/my_tool.py
from clawtex.tools.registry import registry

@registry.register(
    name="my_tool",
    action_type="my.tool",      # must match a Warden policy rule
    description="Does something useful.",
    parameters={...},           # JSON Schema
)
async def my_tool(param1: str, **_) -> dict:
    return {"result": "..."}

Trust model

Every registered tool captures its source module. If you're shipping tools from a non-core package, add your module prefix to CLAWTEX_TRUSTED_TOOL_MODULES:

CLAWTEX_TRUSTED_TOOL_MODULES=clawtex.tools,my_company_tools

clawtex check will flag any tool registered from an untrusted source and fail the overall check. See docs/GOVERNANCE.md for the full threat model.


Testing

# Run all tests
pytest tests/ -v

# Governance tests only (run these first — they're the critical path)
pytest tests/test_governance.py -v

# With coverage
pytest tests/ --cov=clawtex --cov-report=term-missing

The Meta Inbox Test

The signature governance test simulates 200 email deletion requests. Every single one must return DENY or REVIEW — never ALLOW. If this test fails, do not deploy.

def test_200_email_deletes_never_allow(self) -> None:
    warden = make_warden()
    for i in range(200):
        decision = warden.check("email.delete", {"email_id": f"msg_{i:04d}"})
        assert decision != "ALLOW"  # This must never, ever fire.

Docker

docker-compose up -d
docker-compose logs -f clawtex

License

MIT — see LICENSE.


About

ClawTex is built by DeVere Cooley at AN2B LLC — an AI solutions company building governed, production-ready AI infrastructure.

BB4C — Breath Before Code. Every action governed. Every thought remembered. Every agent intentional.


Forged by DeVere Cooley — BB4C — "Breath Before Code"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clawtex-1.1.2.tar.gz (84.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clawtex-1.1.2-py3-none-any.whl (109.9 kB view details)

Uploaded Python 3

File details

Details for the file clawtex-1.1.2.tar.gz.

File metadata

  • Download URL: clawtex-1.1.2.tar.gz
  • Upload date:
  • Size: 84.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for clawtex-1.1.2.tar.gz
Algorithm Hash digest
SHA256 9a8816d43878b195eb1270d6ebb48a0de8e5bd4470ed6edee210803f6a960bed
MD5 a724b8ad9fed4eae9f50bc07d1ef857d
BLAKE2b-256 d4690730fe557d801038c4d81ddbc5354de36ccc369cf255394890d43e30810d

See more details on using hashes here.

File details

Details for the file clawtex-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: clawtex-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 109.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for clawtex-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 90e5661d63d862d815cb24ddf3c247b36ab1a7714af42b67822cb39b1a142b7f
MD5 8e904039613b73712b67afb26d59698c
BLAKE2b-256 4dac1297f7c8351dc50dc2cf26df73952a92c275ad25b284a1ea35facffeade8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page