RAOC is a macOS-only local agent execution framework. A user requests a file or script action from Telegram, reviews the proposed plan, and explicitly approves or denies it before anything runs.
Safety boundaries:
- Human approval before execution
- Workspace-only file access
- Automatic backups before file edits
- Dangerous command blocking
- Verification after execution
- Final report with evidence
RAOC is intentionally not a fully autonomous agent. Flow: user request -> agent builds a plan -> plan sent for approval -> execution only after approval -> file changes backed up -> verification runs -> report sent back. Blocked by design: unrestricted filesystem access, commands outside the workspace, destructive shell patterns, sudo, silent file modification, execution without approval.
- macOS only
- Designed for a single trusted user
- Not intended for server deployment or untrusted workspaces
- Telegram security depends on correct token and user ID configuration
- The command-blocking layer reduces risk but is not a formal sandbox
- What is RAOC?
- How it Works
- What You Need Before Starting
- Step-by-Step Setup
- How to Use RAOC
- Troubleshooting
- Project Structure
- Database Schema
- Configuration
- Running Tests
RAOC is your personal AI assistant that runs on your Mac and listens for commands from your phone via Telegram. It can:
- Rewrite files: "Make my cover letter more formal"
- Run scripts: "Count how many lines are in all my Python files"
- Find and act: "Find my resume and update it with my new job"
- Every action requires your approval on your phone before it runs
- All file changes are backed up automatically
- It can only access files in your designated workspace folder
- Dangerous commands (like
rm -rforsudo) are blocked
You send a message from your phone
↓
Telegram Bot receives it
↓
Intake Agent understands what you want
↓
Discovery Agent finds the target file
↓
Planning Agent creates a step-by-step plan
↓
Plan is sent to your phone → You tap Approve or Deny
↓
Execution Agent carries out the plan
↓
Verification Agent checks everything worked
↓
Reporter sends you proof (screenshot + results)
If you tap Deny, nothing happens. Zero side effects.
RAOC is built for macOS (uses macOS Keychain for secrets).
Check if you have it:
python3 --versionIf you don't have it, install from python.org or use Homebrew:
brew install python@3.12This manages Python packages. Install it:
curl -LsSf https://astral.sh/uv/install.sh | shOr with Homebrew:
brew install uvRAOC uses Claude to understand your requests and rewrite files.
How to get it:
- Go to console.anthropic.com
- Create an account or sign in
- Click "Get API keys"
- Click "Create Key"
- Copy the key (starts with
sk-ant-...) - Save it somewhere safe — you'll need it in step 5
This lets RAOC receive messages from your phone.
How to get it:
- Open Telegram on your phone
- Search for
@BotFatherand start a chat - Send the message:
/newbot - Follow the prompts:
- Give your bot a name (e.g., "My RAOC Bot")
- Give it a username ending in "bot" (e.g.,
myraoc_bot)
- BotFather will give you a token that looks like:
123456789:ABCdefGHIjklMNOpqrsTUVwxyz - Save this token — you'll need it in step 5
RAOC only accepts messages from you (for security).
How to get it:
- In Telegram, search for
@userinfobot - Start a chat
- It will reply with your user ID (a number like
123456789) - Save this number — you'll need it in step 5
cd ~
git clone <repository-url> raoc
cd raocuv syncThis downloads all required packages (may take a few minutes).
This is where RAOC will read and write files:
mkdir -p ~/raoc_workspace/.backups
mkdir -p ~/raoc_workspace/scripts
mkdir -p ~/raoc_workspace/screenshotsPut any files you want RAOC to work on inside ~/raoc_workspace/.
For PDF support, install system dependencies:
# For PDF text extraction
# (Usually already installed on macOS)
# For OCR (reading text from images/PDFs)
brew install tesseractThis is the most important step. Run these three commands in Terminal, replacing the placeholder values with your actual keys:
# Add your Anthropic API key
security add-generic-password -s raoc -a anthropic_api_key -w "sk-ant-your-actual-key-here"
# Add your Telegram bot token
security add-generic-password -s raoc -a telegram_bot_token -w "123456789:your-actual-token-here"
# Add your Telegram user ID
security add-generic-password -s raoc -a telegram_user_id -w "123456789"Important:
- Replace the values in quotes with your actual keys
- Keep the quotes around the values
- The
-s raocpart is required — this is the "service name" - The
-a ...part is the "account name" — don't change these
uv run python -c "from raoc.db.schema import create_tables, get_engine; create_tables(get_engine())"You should see no output if this succeeds.
Run the tests to make sure everything works:
uv run pytest tests/ -v --tb=shortYou should see something like:
=========================== 303 passed in 5.23s ===========================
uv run python -m raoc.mainYou should see:
2026/04/06 17:00:00 - telegram_bot - INFO - Bot started. Listening for messages...
Leave this terminal window open. This is RAOC running.
- Open Telegram
- Find your bot (search for the username you created, like
@myraoc_bot) - Send the message:
Hello
You should get a response within a few seconds. If you do, everything is working!
-
Create a file in your workspace:
echo "The meeting is at 3pm. We should discuss the project." > ~/raoc_workspace/notes.txt
-
From your phone, send:
Rewrite notes.txt to be more professional -
You'll see:
- "Got it. Working on it..."
- "Found notes.txt..."
- A plan preview with Approve/Deny buttons
-
Tap Approve
-
You'll get a report showing what changed
From your phone:
Write a script that counts the files in my workspace and run it
RAOC will:
- Write a Python script
- Show you the script
- Ask for approval
- Run it after you approve
- Send you the output
From your phone:
Find my cover letter and rewrite it for a senior engineering role
RAOC will:
- Search your workspace for files that look like a cover letter
- Ask you to confirm it found the right file
- Build a rewrite plan
- Ask for approval
- Execute and report back
RAOC can rewrite:
- Plain text files (.txt, .md, .py, .sh, etc.)
- CSV files
- JSON files
- Microsoft Word documents (.docx)
- PDF files (converts to .docx for editing)
- ZIP files (extracts and asks which file to work on)
Problem: You get an error when adding API keys.
Solution: Try adding the -T flag to allow Terminal access:
security add-generic-password -s raoc -a anthropic_api_key -w "your-key" -TOr add via the GUI:
- Open "Keychain Access" app
- Click "login" keychain
- Click "+" to add
- Keychain Item Name:
raoc - Account Name:
anthropic_api_key - Password: your actual API key
Check 1: Is RAOC running? Look at the terminal window where you started it.
Check 2: Is your Telegram User ID correct? The bot ignores messages from anyone else.
Check 3: Check the logs:
tail -f ~/raoc/data/raoc.logSolution: Install uv or use the full path:
# Find where uv was installed
which uv
# Or restart your terminal and try againProblem: Some tests fail with import errors.
Solution: Make sure you ran uv sync in the raoc directory:
cd ~/raoc
uv syncSolution: Check your workspace permissions:
ls -la ~/raoc_workspaceThe owner should be your user. If not:
sudo chown -R $(whoami) ~/raoc_workspaceProblem: RAOC says it can't connect to Claude or Telegram.
Check 1: Verify your keys are in Keychain:
security find-generic-password -s raoc -a anthropic_api_key -wThis should print your key.
Check 2: Make sure you used the right account names:
anthropic_api_key(notanthropic-key)telegram_bot_tokentelegram_user_id
raoc/
├── config.py All paths and constants
├── coordinator.py Routes jobs through the agent pipeline
├── main.py Entry point — starts the Telegram bot
│
├── agents/
│ ├── intake.py Understands your request
│ ├── discovery.py Finds and reads files
│ ├── planning.py Creates action plans
│ ├── execution.py Executes actions safely
│ ├── verification.py Verifies results
│ └── reporter.py Sends reports to your phone
│
├── substrate/
│ ├── command_wrapper.py Safe shell command execution
│ ├── host_sampler.py File and system information
│ ├── screenshot.py Takes screenshots
│ ├── secret_broker.py Reads from macOS Keychain
│ ├── llm_client.py Talks to Claude API
│ └── zone_resolver.py Enforces file access boundaries
│
├── gateway/
│ └── telegram_bot.py Telegram interface
│
├── models/
│ ├── job.py Job data structures
│ ├── action.py Action data structures
│ └── scope.py Permission and scope models
│
└── db/
├── schema.py Database table definitions
└── queries.py Database operations
| Boundary | Protection |
|---|---|
| Workspace | All file operations stay inside ~/raoc_workspace/. Paths outside raise an error. |
| Commands | Dangerous patterns (rm -rf, sudo, etc.) are blocked. |
| Approval | No action runs without approval_granted == True. Enforced in code. |
| Secrets | API keys stored in macOS Keychain, never in code or database. |
| Backup | Every file is backed up before rewriting. Auto-restored on failure. |
| Identity | Only your Telegram user ID can send commands. Old messages are ignored. |
RAOC uses SQLite to track all jobs and actions.
| Column | Description |
|---|---|
| job_id | Unique ID for each job |
| raw_request | Your original message |
| task_type | run_script, rewrite_file, query, or query_action |
| target_path | File being worked on |
| status | Current state of the job |
| approval_granted | Whether you approved the plan |
| created_at | When the job started |
Each step in a plan gets a row:
| Column | Description |
|---|---|
| action_id | Unique ID for the action |
| job_id | Which job this belongs to |
| step_index | Order of execution (0, 1, 2...) |
| action_type | file_read, file_write, file_backup, cmd_execute, screenshot |
| risk_level | low, medium, or high |
| intent | Plain English description |
| status | pending, running, succeeded, or failed |
RECEIVED → UNDERSTANDING → DISCOVERING → PLANNING → AWAITING_APPROVAL
↓
EXECUTING → VERIFYING → REPORTING → COMPLETED
(or FAILED / CANCELLED / BLOCKED)
All settings are in raoc/config.py. Common ones:
| Setting | Default | Description |
|---|---|---|
WORKSPACE |
~/raoc_workspace |
Where your files live |
MAX_FILE_SIZE_CHARS |
50,000 | Largest file RAOC will rewrite |
MAX_COMMAND_TIMEOUT |
30 seconds | Scripts killed if they run longer |
LLM_MODEL |
claude-sonnet-4-5 |
AI model for understanding requests |
NARRATOR_MODEL |
claude-haiku-4-5 |
AI model for status messages |
uv run pytest tests/ -vuv run pytest tests/test_coordinator.py -vuv run pytest tests/ --cov=raocTests use temporary directories — your real workspace is never touched.
| Component | Technology |
|---|---|
| Language | Python 3.12 |
| Package Manager | uv |
| AI | Anthropic Claude |
| Database | SQLite with SQLAlchemy |
| Telegram | python-telegram-bot |
| Validation | Pydantic v2 |
| Screenshots | pyautogui + Pillow |
| PDF Support | pdfplumber, pymupdf, pdf2docx |
| Secrets | macOS Keychain via keyring |
These features are planned for future phases:
- Web browsing
- GUI automation (clicking desktop apps)
- Gmail/Calendar integration
- Multi-file operations in one job
- Semantic search across files
- Background daemon mode
- Memory and preference learning
- Check the logs:
tail -f ~/raoc/data/raoc.log - Run tests to verify setup:
uv run pytest tests/ -v - Check that your API keys are correct in Keychain Access
- Make sure your Telegram bot token and user ID are correct
[Add your license information here]