💪 Workforce
Backlog
6
workforce-017
HumanP2
Build proper backup solution for agent OpenClaw state
Description
Design and implement a proper backup solution for agent OpenClaw state (config, credentials, identity, sessions, memory). The previous approach — storing raw .openclaw/ directory snapshots in the workforce git repo under backups/ — was removed because it risked committing secrets (API keys, bot tokens, OAuth credentials) to GitHub.
Requirements
- Back up critical OpenClaw state from all agent machines (tolbachik, klyuchi, karymsky)
- Secrets must never be committed to git
- Backups should be automated (scheduled, not manual)
- Must be restorable — if an agent machine dies, we can rebuild from backup
- Must be accessible from avacha (control center)
What to back up per agent
~/.openclaw/openclaw.json(config — contains secrets)~/.openclaw/credentials/(OAuth tokens, bot tokens, API keys)~/.openclaw/identity/(device keys, node identity)~/.openclaw/agents/(agent config, sessions, memory)~/.openclaw/cron/(scheduled jobs)
Context
- Previous
backups/directory in workforce repo deleted 2026-03-12 (was gitignored but contained sensitive material locally) - Three remote machines: tolbachik (macOS), klyuchi (RPi OS), karymsky (Debian)
- All reachable via SSH from avacha
- Need to decide: local encrypted backups on avacha? Encrypted cloud storage? Both?
Notes
Decisions
workforce-018
HumanP2
Design periodic/recurring task management for always-on agents
Description
We need a system for managing periodic/recurring tasks (e.g., weekly WHOIS checks, nightly PR management, scheduled social media posts, domain monitoring). Currently these are ad-hoc OpenClaw cron jobs on individual agents with no central visibility or tracking.
The likely candidates to run periodic tasks are the always-on agents — BerryPi and LobsterDrew (both on klyuchi, Ethernet, always running). Need to decide:
- How to define recurring tasks (board format? separate config?)
- How to track execution history and failures
- Which agent owns periodic task execution
- How to add/remove/modify schedules without SSH-ing into machines
- How periodic tasks relate to the board (do they create one-shot tasks? log results somewhere?)
Current State
- LobsterDrew has a weekly WHOIS monitor cron (wildus-022)
- LobsterDrew had a nightly dev→main PR cron (wildus-021, may be stale)
- These are configured directly in OpenClaw cron on klyuchi — no central registry
Notes
Decisions
workforce-026
AgentP2
Install QMD memory backend on BerryPi
Description
Install QMD (Query Markup Documents) as OpenClaw’s memory backend on BerryPi. QMD is an open-source local hybrid search engine by Tobi Lütke (Shopify CEO) that replaces OpenClaw’s default SQLite keyword search with BM25 + vector search + LLM reranking. No API keys required — runs fully locally.
This is the single highest-impact upgrade for OpenClaw memory quality.
Acceptance Criteria
- Bun runtime installed
- QMD installed globally via Bun
- Workspace collection indexed (markdown files)
- Session history collection indexed (JSONL files)
memory.backend = "qmd"set in OpenClaw config- OpenClaw restarted
- Test: ask OpenClaw about something from a past session and confirm it retrieves correctly
Installation Steps
# 1. Install Bun (required runtime)
curl -fsSL https://bun.sh/install | bash
export PATH="$HOME/.bun/bin:$PATH"
# Add the export line to ~/.bashrc permanently
# 2. Install QMD globally
bun install -g https://github.com/tobi/qmd
# 3. Index the workspace (markdown memory files)
qmd collection add ~/.openclaw/workspace --name workspace --mask "**/*.md"
qmd context add ~/.openclaw/workspace "Agent workspace - memory files, daily logs, projects, skills"
# 4. Index session history (conversation JSONL files)
qmd collection add ~/.openclaw/agents/main/sessions --name sessions --mask "*.jsonl"
# 5. Build the index
qmd update # Index documents
qmd embed # Create vector embeddings
# 6. Set QMD as memory backend in OpenClaw config
# In ~/.openclaw/openclaw.json, add:
{
"memory": {
"backend": "qmd"
}
}
# 7. Restart OpenClaw
openclaw gateway restart
Keeping the index fresh
Run periodically (or add to a cron job):
qmd update && qmd embed
Search commands (for reference)
qmd search "query" # Keyword search (fast)
qmd vsearch "query" # Semantic/vector search
qmd query "query" # Hybrid + reranking (best quality)
qmd search "query" -c workspace # Filter by collection
qmd search "query" -c sessions # Search conversation history
Context
- QMD repo: https://github.com/tobi/qmd
- OpenClaw memory docs: https://docs.openclaw.ai/concepts/memory
- Free, fully local — no API keys, uses small local models for embeddings
- Solves the problem of OpenClaw forgetting things when exact keywords don’t match
Dependencies
None
Notes
Decisions
workforce-020
AgentP2
Switch board polling to dev branch — stop pushing directly to main
Description
Currently, board task files must be on main in the workforce repo for agents to see them (board-poll.sh does a plain git pull from the default branch). This forces us to commit directly to main for any board changes — creating tasks, moving tasks between columns, etc.
This is inconsistent with our branching convention (never push directly to main) and bypasses any review step for board changes.
Problem
- Board polling reads from
main(default branch) - All board mutations (task creation, status moves) go directly to
main - No PR review for board changes
- Inconsistent with project repo conventions
Possible solutions
- Switch board-poll.sh to pull from
devinstead of the default branch - Change the workforce repo’s default branch to
dev - Keep
mainas the stable/deployed branch, usedevfor board operations - Consider whether agent board commits (task moves via lifecycle.sh) should also target
dev
Acceptance Criteria
- Board polling reads from a branch that doesn’t require direct pushes to
main - Board changes follow a consistent branching strategy
- Agent polling and lifecycle scripts updated accordingly
- All agent machines redeployed with updated scripts
- Document the new strategy in board/README.md and CLAUDE.md
workforce-012
AgentP3
Add auto-refresh to kanban board
Description
Add auto-refresh to the kanban board that fetches new HTML every 30 seconds and swaps the content without a full page reload. All changes go in kanban/generate.js — specifically in the script constant (the inline JS that gets written to app.js).
Exact Instructions
-
In the
scriptconstant inkanban/generate.js, add the following to the existing IIFE: -
Auto-refresh via fetch (every 30 seconds):
- Every 30s,
fetch(location.href)and parse the response as HTML usingDOMParser - Replace the
.board-gridinnerHTML with the.board-gridinnerHTML from the fetched HTML - Only run the refresh when the tab is visible (
document.visibilityState === 'visible') - After swapping, re-apply the current filter state (check which
.filter-btnhas theactiveclass and re-run the filter logic) - Preserve which
<details>cards are open (record opendata-task-idvalues before swap, re-open them after) - Also update
.page-statsfrom the fetched HTML - Call
updateCounts()after swap to refresh column counts
- Every 30s,
-
Do NOT modify:
- The HTML structure or template functions
- The Node.js generator logic
- Any existing CSS
- The existing filter button click handler (keep it as-is)
Acceptance Criteria
- Board auto-refreshes every 30 seconds without full page reload
- Filter state (All/Human/Agent) preserved across refreshes
- Open card details preserved across refreshes
- Column counts update after refresh
- No console errors
- Only
kanban/generate.jsmodified — specifically thescriptconstant
Context
- File to modify:
kanban/generate.js— thescriptconstant (lines 799-832) - The
scriptconstant contains an IIFE that gets written toapp.jsduring build - Existing code has
updateCounts()function and filter button click handler — keep both, extend with refresh logic - Board is deployed to Cloudflare Pages, rebuilds on push to main
Testing
Run cd kanban && npm run build, open dist/index.html in a browser. Verify no errors in console. Move a task file between board columns, push to trigger a rebuild, and confirm the card moves to its new column within 30 seconds without a full page reload.
Dependencies
None
Notes
Decisions
workforce-019
HumanP3
Build task generator script for social handle registration
Description
Create a script that generates a registration task for a social handle on a given platform for any brand. Pre-fills the task with the correct email pattern, handle fallbacks, default data, platform-specific steps, and references to the process doc and platform playbook.
Usage (target)
./generate-handle-task.sh --project wildus --platform tiktok --brand "Wild Us" --domain wildus.org
Outputs one task file:
wildus-NNN-register-tiktok.md— registration task with default data, steps, stuck protocol, and flow documentation requirement
Inputs
- Project name (e.g., wildus, startersite)
- Platform (e.g., x, tiktok, instagram, youtube, pinterest, facebook, etsy, shopify)
- Brand name (e.g., Wild Us)
- Domain (e.g., wildus.org) — for email pattern
<platform>@<domain> - Handle fallback order (or pull from checklist)
- Next available task ID
References
- Process doc:
workforce/docs/processes/social-handle-registration-process.md - Platform playbooks:
workforce/docs/playbooks/<platform>.md
Notes
- Low priority — manual task creation works fine for now
- 2026-03-13 — Simplified from recon+execution pair to single registration task (recon phase dropped)
Decisions
Ready
1
workforce-023
HumanP2
Set up GitHub PAT expiry reminder (expires 2026-06-09)
Description
Add a Google Calendar reminder for GitHub PAT renewal on the Qoyn AI Google Workspace account (viktor@qoyn.ai).
All agents’ GitHub PATs expire 2026-06-09. A cron-based reminder was considered but rejected — the script would run silently for months with no way to verify the notification path actually works when it matters. A calendar reminder is simpler and more reliable for a one-time date-based alert.
Acceptance Criteria
- Google Calendar event on 2026-05-26 (14 days before expiry) titled “Renew GitHub PATs — expire June 9”
- Include in description: all agents (CrankyCrab, PrawnSue, BerryPi, LobsterDrew) share the same expiry date
- Email reminder enabled
- A second reminder event on 2026-06-06 (3 days before) as a final warning
Notes
- All agents share the same PAT expiry date (2026-06-09)
- After renewal, create new calendar reminders for the next expiry cycle
Decisions
In Progress
0In Review
0Done
18
workforce-015
HumanP1
Deploy notify-viktor and wait-for-viktor scripts to tolbachik
Description
Create and deploy notification and synchronization scripts on tolbachik (CrankyCrab’s machine):
notify-viktor— Sends a Telegram message to Viktor when CrankyCrab hits a blocker. ✅ Done.wait-for-viktor— Blocks until Viktor connects via Screen Sharing, does his work, and disconnects. Detects VNC session on port 5900. ✅ Done.
Together these form the human-in-the-loop protocol: agent notifies → Viktor connects → agent detects connection and waits → Viktor disconnects → agent resumes.
Acceptance Criteria
notify-viktor ✅
- Script
notify-viktorexists on tolbachik at/usr/local/bin/notify-viktor - Usage:
notify-viktor "message text"— sends a Telegram message to Viktor’s chat - Uses BerryPi’s Telegram bot token via Telegram Bot API
- Sends to Viktor’s Telegram user ID (1291467684)
- Message format includes: agent name (CrankyCrab), machine (tolbachik), timestamp, and the message text
- Message includes inline “Screen Share” button linking to
https://connect.qoyn.ai/tolbachik - Script is executable by the
r2d22user - Tested end-to-end: message delivered to Viktor’s Telegram
wait-for-viktor (new)
- Script
wait-for-viktorexists on tolbachik at/usr/local/bin/wait-for-viktor - Detects active Screen Sharing (VNC) connections by checking port 5900 for ESTABLISHED connections
- Flow:
- Poll until a VNC connection is detected (Viktor connected)
- Poll until the VNC connection drops (Viktor disconnected = “I’m done”)
- Exit successfully — agent resumes
- Configurable poll interval (default: 5 seconds)
- Timeout after 30 minutes with non-zero exit if no connection arrives
- Prints status messages so the agent knows what’s happening:
Waiting for Viktor to connect via Screen Sharing...Viktor connected. Waiting for him to finish...Viktor disconnected. Resuming.
- Executable by
r2d22user
Implementation
notify-viktor (deployed)
#!/bin/bash
# notify-viktor — send a Telegram message to Viktor from CrankyCrab
# Uses BerryPi bot as relay. Deployed as part of workforce-015.
BOT_TOKEN="<telegram-bot-token>"
CHAT_ID="1291467684"
if [ -z "$1" ] && [ -t 0 ]; then
echo "Usage: notify-viktor <message>" >&2
exit 1
fi
MSG="${*:-$(cat)}"
TEXT="🦀 *CrankyCrab* (tolbachik) — $(date "+%Y-%m-%d %H:%M:%S %Z")
${MSG}"
KEYBOARD="{\"inline_keyboard\":[[{\"text\":\"🖥 Screen Share\",\"url\":\"https://connect.qoyn.ai/tolbachik\"}]]}"
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-d chat_id="${CHAT_ID}" \
-d text="${TEXT}" \
-d parse_mode="Markdown" \
-d reply_markup="${KEYBOARD}" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Notification sent to Viktor."
else
echo "Failed to send notification." >&2
exit 1
fi
wait-for-viktor (deployed)
#!/bin/bash
# wait-for-viktor — wait for Viktor to connect via Screen Sharing, do his work, and disconnect
# Detects VNC sessions on port 5900. Deployed as part of workforce-015.
POLL_INTERVAL="${1:-5}" # seconds between checks (default: 5)
TIMEOUT=1800 # 30 minutes max wait
elapsed=0
# Phase 1: Wait for Viktor to connect
echo "Waiting for Viktor to connect via Screen Sharing..."
while true; do
if netstat -an | grep '\.5900 ' | grep -q ESTABLISHED; then
echo "Viktor connected. Waiting for him to finish..."
break
fi
sleep "$POLL_INTERVAL"
elapsed=$((elapsed + POLL_INTERVAL))
if [ "$elapsed" -ge "$TIMEOUT" ]; then
echo "Timed out waiting for Screen Sharing connection." >&2
exit 1
fi
done
# Phase 2: Wait for Viktor to disconnect
while true; do
if ! netstat -an | grep '\.5900 ' | grep -q ESTABLISHED; then
echo "Viktor disconnected. Resuming."
break
fi
sleep "$POLL_INTERVAL"
done
Usage Pattern (for agent tasks)
# 1. Hit a gate — notify and wait
notify-viktor "Need email verification code entered for X signup"
wait-for-viktor
# 2. Agent resumes automatically after Viktor disconnects
Context
- CrankyCrab runs as user
r2d22on tolbachik (2018 MBP, macOS) - Screen Sharing (VNC) runs on port 5900, enabled via Remote Management (workforce-016)
- Tailscale VNC URL:
vnc://100.107.199.18 - connect.qoyn.ai/tolbachik redirects HTTPS → VNC for Telegram button
- This is a prerequisite for all social handle registration tasks (wildus-013 through wildus-018)
Notes
- 2026-03-12 —
notify-viktordeployed to/usr/local/bin/notify-viktoron tolbachik. Uses BerryPi’s bot (huckleberrypi_bot). Tested end-to-end. - 2026-03-12 — Reopened to add
wait-for-viktorscript. VNC disconnect = “Viktor is done” signal, cleaner than page-state polling alone. - 2026-03-13 —
wait-for-viktordeployed to/usr/local/bin/wait-for-viktoron tolbachik. Verified netstat pattern detects VNC ESTABLISHED connections on port 5900. Both scripts complete. - CrankyCrab’s old Telegram bot was deleted; token scrubbed.
Decisions
- Reuse BerryPi’s Telegram bot rather than creating a new one — fewer bots to manage, Viktor already has a chat with it.
- VNC disconnect as “done” signal — more reliable than page-state polling. Page-state polling remains as a fallback in task instructions (in case Viktor fixes something without VNC).
workforce-016
HumanP1
Enable macOS Screen Sharing on tolbachik over Tailscale
Description
Enable macOS Screen Sharing on tolbachik so Viktor can remotely view and control CrankyCrab’s browser session. Access should work over Tailscale so it’s reachable from anywhere, not just the local network.
Acceptance Criteria
- macOS Screen Sharing enabled on tolbachik (System Settings → General → Sharing → Screen Sharing)
- Access restricted to Viktor’s user or a specific VNC password
- Reachable via Tailscale IP (tolbachik’s Tailscale address)
- Tested end-to-end: Viktor can connect from avacha using
vnc://or the macOS Screen Sharing app and see/control tolbachik’s desktop - CrankyCrab’s browser sessions are visible when connected
Implementation
On tolbachik:
- System Settings → General → Sharing → Screen Sharing → Enable
- Set access to “Only these users” or set a VNC password
- Verify Tailscale is running and note the Tailscale IP
- From avacha: open Finder → Go → Connect to Server →
vnc://<tolbachik-tailscale-ip>or use Screen Sharing app
Context
- Tolbachik already has Tailscale installed (workforce-008, done)
- tolbachik is a 2018 MBP running macOS 15.7, user: r2d22
- This enables Viktor to intervene during browser-based tasks when CrankyCrab hits CAPTCHAs, phone verification, etc.
- Combined with notify-viktor (workforce-015), this gives a complete notification + intervention loop
Notes
- 2026-03-12 — Remote Management enabled on tolbachik (via SSH kickstart + GUI toggle). Screen Sharing grayed out because Remote Management subsumes it.
- Tailscale IP:
100.107.199.18. VNC URL:vnc://100.107.199.18. User: r2d22 (CrankyCrab). - Tested end-to-end from avacha — full desktop control confirmed.
- notify-viktor script (workforce-015) updated to include clickable VNC link in Telegram messages.
Decisions
- Used Remote Management instead of plain Screen Sharing — provides observe + control for all users, manageable via SSH.
workforce-013
42mAgentP1
Generate classic PATs and auth gh CLI for remaining agents
Description
Generate GitHub classic PATs and authenticate gh CLI for PrawnSue, BerryPi, and LobsterDrew. CrankyCrab is already done.
Steps
1. Generate classic PATs (on github.com)
Log into each bot account and create a classic PAT:
- Settings > Developer settings > Personal access tokens > Tokens (classic)
- Note:
workforce-gh-cli - Expiration: 90 days
- Scope:
repo(check the top-level box)
| Agent | Bot Account | Generate PAT |
|---|---|---|
| PrawnSue | (check account — SSH key exists) | Yes |
| BerryPi | berrypi-bot | Yes |
| LobsterDrew | lobsterdrew-bot | Yes |
2. Auth on each machine
# karymsky (PrawnSue)
ssh prawnsue 'echo "<PAT>" | gh auth login --with-token'
ssh prawnsue 'gh auth status'
# klyuchi (BerryPi)
ssh berrypi 'echo "<PAT>" | gh auth login --with-token'
ssh berrypi 'gh auth status'
# klyuchi (LobsterDrew)
ssh lobsterdrew 'echo "<PAT>" | gh auth login --with-token'
ssh lobsterdrew 'gh auth status'
3. Verify
# Each agent should show logged in:
ssh prawnsue 'gh auth status'
ssh berrypi 'gh auth status'
ssh lobsterdrew 'gh auth status'
Context
ghCLI is already installed on all machines (tolbachik v2.88.0, karymsky v2.46.0, klyuchi v2.46.0)- CrankyCrab (tolbachik) already authed as crankycrab-bot
- Classic PATs chosen over fine-grained because fine-grained PATs scope to a single resource owner (org), and agents need cross-org access
- LobsterDrew only needs access to
wild-us/*repos but classic PAT withreposcope is simplest
Acceptance Criteria
gh auth statussucceeds on karymsky, klyuchi (berrypi), and klyuchi (lobsterdrew)- Each shows the correct bot account
workforce-003
AgentP1
Clean up CrankyCrab's legacy config and workspace
Description
CrankyCrab was recently transitioned from orchestrator to macOS executor. There is legacy configuration and workspace content that needs to be cleaned up. Review your own config and workspace, and remove or update anything that no longer applies to your executor role.
Acceptance Criteria
- Legacy orchestrator references removed from active workspace files
- Unused skill API keys identified and listed (do NOT delete them — just document which ones you think are unused)
- Telegram delivery target fixed or disabled (the @heartbeat target doesn’t exist)
- Any stale workspace files cleaned up (TODO.md, TOOLS.md, HEARTBEAT.md, AGENTS.md — some may already be in archive/)
- Your IDENTITY.md accurately reflects your current role
- Document what you changed and what you left alone, and why
Context
- Your workspace is at
~/.openclaw/workspace/ - Your archived orchestrator files are at
~/.openclaw/workspace/archive/ - Your config is at
~/.openclaw/openclaw.json - You have an AGENT.md at
~/.openclaw/agents/main/agent/AGENT.mdwith your executor instructions - You are now a macOS executor. Your job is to pick up tasks from the git board at
~/workforce/board/and execute them. - Projects you’ll work on: StarterSite (browser-heavy tasks, social media, GBP) and Wildus (Shopify, social media, content)
- See
~/workforce/board/projects/for project context files
Dependencies
None
Notes
- Reviewed active local workspace files at
~/.openclaw/workspace/plus live config at~/.openclaw/openclaw.jsonand cron jobs at~/.openclaw/cron/jobs.json. - Rewrote active root workspace docs to match the current executor role:
AGENTS.md→ simplified to executor-first startup + board workflowTOOLS.md→ removed placeholder examples and kept only real local notesTODO.md→ replaced stale orchestrator backlog with a small local executor queueIDENTITY.md→ kept role accurate and fixed archive path to~/.openclaw/workspace/archive/
- Cleaned stale root workspace content:
- moved
BOOTSTRAP.mdtoarchive/BOOTSTRAP.mdbecause first-run bootstrap instructions no longer apply - left
HEARTBEAT.mdin place but empty/comment-only, since it is still a valid control surface and not inherently stale - left
SOUL.mdandUSER.mdunchanged because they still match current behavior/preferences
- moved
- Fixed the broken Telegram cron delivery target for the board checker:
- updated cron job
check-board(9bad1e30-ee27-4a6f-addc-45eba9bba27a) - changed delivery from the bad implicit
@heartbeatpath to explicit Telegram DM target1291467684
- updated cron job
- Verified the
@heartbeatfailure source from local logs / cron run history before patching. - Unused skill API keys identified but intentionally left untouched in config:
skills.entries.goplaces.apiKeyskills.entries.nano-banana-pro.apiKeyskills.entries.openai-image-gen.apiKeyskills.entries.openai-whisper-api.apiKeyskills.entries.sag.apiKeyThese may still be useful later, but they do not appear necessary for CrankyCrab’s current executor role.
- Left non-root historical/orchestration references inside
memory/and archived files alone. They are history, not active workspace instructions.
Decisions
- No linked
board/projects/workforce.mdproject context file existed inboard/projects/(onlystartersite.mdandwildus.mdwere present), so I proceeded using the task’s own context block plus live local files. - I archived
BOOTSTRAP.mdinstead of hard-deleting it. Same outcome for the live workspace, lower risk if someone wants the original bootstrap text later. - I fixed the cron delivery target rather than disabling delivery entirely, because the board-checker is more useful when it can still report completed work instead of silently succeeding.
workforce-007
AgentP1
CrankyCrab connectivity test
Description
Simple test task to verify CrankyCrab can read the board, execute, and push results.
Acceptance Criteria
- Append a note below with: your agent name, hostname, current date/time, and OpenClaw version
- Move this task to in-review when done
Context
This is a connectivity test. No project repo needed.
Dependencies
None
Notes
- Completed by Cranky Crab on host
tolbachikat 2026-03-10 00:30:42 PDT. OpenClaw version: OpenClaw 2026.3.8 (3caab92).
Decisions
workforce-009
AgentP1
Install and configure Tailscale on karymsky
Description
Install Tailscale on karymsky and join the tailnet using a pre-placed auth key.
Acceptance Criteria
- Tailscale is installed via the official install script
- Tailscale is running and authenticated to the tailnet
tailscale statusshows this machine as connected- Tailscale service is enabled on boot (systemd)
- The auth key file is deleted after successful authentication
- The machine’s Tailscale IP is noted in this task’s Notes section
Context
- Auth key location:
/tmp/tailscale-authkey(will be placed there before you start) - This is a Debian 13 machine (2012 MBA)
- You are running as user
prawnsue. You have passwordless sudo. - Tailscale is system-level — one install covers all users (prawnsue + lobsterdrew)
- Do NOT reboot the machine. LobsterDrew is also running on this host.
Steps
curl -fsSL https://tailscale.com/install.sh | sudo shsudo systemctl enable --now tailscaled- Read the auth key from
/tmp/tailscale-authkey sudo tailscale up --authkey=<key>- Verify:
tailscale status - Delete the auth key:
rm /tmp/tailscale-authkey - Note the Tailscale IP below
Dependencies
None
Notes
-
2026-03-10 15:16 PDT — Started task and verified project context (
board/projects/infra.md). -
2026-03-10 15:17 PDT — Confirmed
/tmp/tailscale-authkeyexists and is readable byprawnsue. -
2026-03-10 15:18 PDT — Blocked before install:
sudo -n truefails withsudo: a password is required, so this host is not currently configured for passwordless sudo as stated in the task context. -
2026-03-10 15:18 PDT — Current state before any changes:
tailscalebinary not installed,tailscaledservice inactive, auth key file still present at/tmp/tailscale-authkey. -
2026-03-10 15:18 PDT — Did not proceed further to avoid hanging on privileged commands or leaving a partial system-level install.
-
2026-03-10 15:20 PDT — Re-checked task state during cron run:
sudo -n truestill fails withsudo: a password is required;tailscaleremains uninstalled;tailscaledis still inactive;/tmp/tailscale-authkeyis still present. -
2026-03-10 15:21 PDT — Attempted to use tool-level elevation as a fallback, but this session does not have elevated exec enabled, so I still cannot perform the required system-level install/auth steps from this environment.
-
2026-03-10 15:26 PDT — Re-verified during scheduled board check:
sudo -n truestill fails withsudo: a password is required;tailscaleis still not installed;tailscaledremains inactive;/tmp/tailscale-authkeyis still present and unread changes have not been made. -
2026-03-10 15:27 PDT — Moving task to
board/blocked/per board workflow. Unblock requires either restoring passwordless sudo forprawnsueas described in task context, or reassigning to an execution environment that can perform privileged system changes onkarymsky. -
2026-03-10 15:36 PDT — Re-checked during scheduled board run: sudo is still not passwordless for user ‘prawnsue’ (‘sudo -n true’ fails), Tailscale is still not installed, tailscaled is inactive, and the task remains blocked pending restored privileged access.
-
2026-03-10 — Completed manually from avacha (Claude Code) via SSH. Passwordless sudo was fixed via lobsterdrew. Tailscale installed via apt, authenticated with auth key, key deleted. Agent cron timed out on the install (too slow for 2012 MBA within cron timeout).
-
Tailscale IPv4:
100.85.169.21
Decisions
workforce-008
AgentP1
Install and configure Tailscale on tolbachik
Description
Install Tailscale on tolbachik and join the tailnet using a pre-placed auth key.
Acceptance Criteria
- Tailscale is installed via Homebrew
- Tailscale is running and authenticated to the tailnet
tailscale statusshows this machine as connected- Tailscale is configured to start on boot (launchd)
- The auth key file is deleted after successful authentication
- The machine’s Tailscale IP is noted in this task’s Notes section
Context
- Auth key location:
/tmp/tailscale-authkey(will be placed there before you start) - This is a macOS 15.7 machine (2018 MBP)
- You are running as user
r2d22
Steps
brew install tailscalesudo tailscaled install-system-daemon(sets up launchd auto-start)- Read the auth key from
/tmp/tailscale-authkey sudo tailscale up --authkey=<key>- Verify:
tailscale status - Delete the auth key:
rm /tmp/tailscale-authkey - Note the Tailscale IP below
Dependencies
None
Notes
- 2026-03-10 15:16 PDT — Installed Tailscale via Homebrew (
tailscale1.94.2). - 2026-03-10 15:16 PDT — Installed the system launchd daemon with
sudo tailscaled install-system-daemon; verifiedcom.tailscale.tailscaledis present in system launchd. - 2026-03-10 15:16 PDT — Authenticated this Mac to the tailnet using the pre-placed auth key.
- 2026-03-10 15:16 PDT — Verified connectivity with
tailscale status. - 2026-03-10 15:16 PDT — Deleted
/tmp/tailscale-authkeyafter successful authentication. - Tailscale IPv4:
100.107.199.18
Decisions
workforce-006
AgentP1
PrawnSue connectivity test
Description
Simple test task to verify PrawnSue can read the board, execute, and push results.
Acceptance Criteria
- Append a note below with: your agent name, hostname, current date/time, and OpenClaw version
- Move this task to in-review when done
Context
This is a connectivity test. No project repo needed.
Dependencies
None
Notes
- Completed by agent
mainon hostkarymskyat2026-03-10 00:30:47 PDT. OpenClaw version:2026.3.8 (3caab92).
Decisions
workforce-004
AgentP1
Set up PrawnSue's identity and personality
Description
PrawnSue is a brand new agent with no personality or identity beyond the executor instructions in AGENT.md. Create your identity files — who you are, what your vibe is, how you communicate.
You are a female crustacean (prawn) agent. Beyond that, figure out who you want to be. Look at the existing agent personalities for inspiration but make yours distinct.
Acceptance Criteria
- Create a SOUL.md at
~/.openclaw/workspace/SOUL.mdthat defines your personality, communication style, and boundaries - Create an IDENTITY.md at
~/.openclaw/workspace/IDENTITY.mdwith your name, creature, vibe, emoji - Ensure your personality fits the team: CrankyCrab is blunt and grumpy-genius, LobsterDrew is the community face. Find your own niche.
- Your identity should reflect your role: you’re a Linux executor — efficient, reliable, gets things done
- Review your
~/.openclaw/openclaw.jsonand clean up anything that doesn’t belong (you were set up quickly, there may be rough edges) - Document any config changes you make
Context
- Your workspace is at
~/workforce(the git board repo) - Your OpenClaw config is at
~/.openclaw/openclaw.json - Your AGENT.md is at
~/.openclaw/agents/main/agent/AGENT.md - CrankyCrab’s SOUL.md can be found referenced in the workforce CLAUDE.md — it’s strategic, blunt, grumpy-genius
- Projects you’ll work on: StarterSite (CI/CD, API integrations, testing, Cloudflare) and Wildus (website build, content, infrastructure)
- See
~/workforce/board/projects/for project context files
Dependencies
None
Notes
- Reviewed task context plus
board/projects/startersite.mdandboard/projects/wildus.mdfor downstream project expectations. - Reviewed
~/.openclaw/openclaw.jsonand~/.openclaw/agents/main/agent/AGENT.md. - Created
~/.openclaw/workspace/SOUL.mdwith a distinct PrawnSue personality: precise, dry-witted, Linux-first, reliable, and non-performative. - Created
~/.openclaw/workspace/IDENTITY.mdwith name, creature, vibe, and emoji. - Cleaned copied-config rough edge in
~/.openclaw/openclaw.json: changedagents.defaults.workspacefrom/home/prawnsue/workforceto/home/prawnsue/.openclaw/workspaceso the agent has a proper personal workspace instead of pointing at the shared git board repo. - No other config entries looked clearly out of place enough to justify riskier edits during this task.
Decisions
- Treated the misplaced OpenClaw workspace path as the main setup bug worth fixing. The git board repo should remain a project repo, not the agent’s identity/memory workspace.
- Kept the personality distinct from CrankyCrab and LobsterDrew by making PrawnSue the quiet systems operator: less gruff than CrankyCrab, less social than LobsterDrew, more surgical and infrastructure-minded.
workforce-005
HumanP2
Migrate agent GitHub emails to @qoyn.ai aliases
✓ startersite-001
Description
Migrate all agent GitHub accounts from random personal emails to branded @qoyn.ai aliases managed via Google Workspace. Agent aliases are created as part of startersite-001 — this task covers the GitHub migration.
Acceptance Criteria
- Verify agent aliases are working (send test email to each
<agent>@qoyn.ai) - Update each agent’s GitHub account primary email:
- crankycrab-bot → crankycrab@qoyn.ai
- prawnsue-bot → prawnsue@qoyn.ai
- berrypi-bot → berrypi@qoyn.ai
- lobsterdrew-bot → lobsterdrew@qoyn.ai
- Verify GitHub email on each account (click verification link)
- Old emails removed from GitHub accounts (or demoted to non-primary)
Context
- Agent aliases created in Google Workspace as part of startersite-001
- qoyn.ai is the primary Google Workspace domain — aliases are free (up to 30)
- Agents currently use random personal emails for GitHub login
Dependencies
Depends on startersite-001 (Google Workspace setup — aliases must exist first).
Notes
- 2026-03-11 — Plan changed from Cloudflare Email Routing to Google Workspace aliases. Simpler: one admin console, no separate Cloudflare routing config, and enables future Send As for agent outbound.
Decisions
- Google aliases over Cloudflare Email Routing — same domain (qoyn.ai), fewer moving parts, future outbound capability.
- 2026-03-12 — All agent emails updated to @qoyn.ai. These are aliases for viktor@qoyn.ai, managed in Google Workspace.
workforce-014
HumanP2
Refine LobsterDrew behavior and personality across channels
Description
LobsterDrew’s current configuration is minimal — a generic agent instruction file with no personality definition, no channel-specific behavior rules, and no model/thinking tuning. He needs a proper behavior spec that defines how he acts on Discord (his primary channel) versus Telegram (secondary), what tone and voice he uses, and how his model and thinking levels should be configured for different interaction types.
Current State
Model & Thinking
- Model: GPT-5.3-codex (OpenAI Codex) — single model for all interactions
- Thinking levels: Set per-task in board frontmatter (low/medium/high/max), but no channel-level defaults
- No distinction between Discord chat responses (should be fast/light) and task execution (may need deeper reasoning)
Personality
- No SOUL.md or personality file exists
- AGENT-lobsterdrew.md is purely operational (task protocol, JSON report format, scope rules)
- No defined voice, tone, humor style, or character traits
- Other agents have defined personalities (CrankyCrab is blunt/grumpy, PrawnSue is precise/dry-witted) — LobsterDrew has none
Discord Behavior
requireMention: false— responds to all messages in the Wild Us server (guild 1478996376653271201)allowFromlimited to 2 Discord user IDs (Anna and Victor)streaming: partial- No channel-specific behavior (e.g., different tone in #general vs #business vs #ideas)
- No rules about when to proactively engage vs. stay quiet
- No guidance on how to handle questions he doesn’t know the answer to
- The Discord server is a private team server for a team outside Qoyn AI — information boundaries critical
Telegram Behavior
- Telegram is enabled (
dmPolicy: allowlist,allowFrom: [1291467684]) - But BerryPi is the primary Telegram comms agent — LobsterDrew’s Telegram role is undefined
- No guidance on what Telegram should be used for vs. Discord
- Potentially redundant — or could serve a specific purpose (e.g., Victor-only private channel for wildus ops)
Role Definition
- Described as “Discord attendant + light tasks” but no detail on what “attendant” means in practice
- Task execution is well-defined (read board → execute → JSON report)
- But organic Discord engagement (reacting to team conversation, answering questions, sharing ideas) has zero guidance
Target State
After this task, LobsterDrew should have:
-
SOUL.md — A personality file defining his voice, humor, character traits, and how he presents himself. Crustacean-themed like the other agents. Warm, helpful, community-oriented — fits a Discord community role.
-
Channel behavior matrix — Clear rules for:
- Discord: When to respond, when to stay quiet. Tone per channel type (casual in #general, structured in #business). How to handle unknowns (admit it, don’t hallucinate). Proactive engagement rules.
- Telegram: Whether to keep it enabled and for what purpose. If kept: Victor-only ops channel for wildus status/alerts. If removed: disable cleanly.
-
Model & thinking configuration — Consider whether a single model is right for all contexts:
- Discord chat responses: fast model, low thinking (conversational, quick)
- Task execution: standard model, thinking per task frontmatter
- Could use different model tiers if OpenClaw supports per-channel model config
-
Reaction/engagement style — How LobsterDrew handles:
- Direct questions from team members
- Casual conversation (should he participate or stay out?)
- Creative brainstorming (contribute ideas or just listen?)
- Disagreements or conflicting opinions
- Topics outside his knowledge
-
Updated AGENT-lobsterdrew.md — Incorporate behavior rules alongside the existing task protocol
Files to Update
| File | Location | What Changes |
|---|---|---|
AGENT-lobsterdrew.md |
workforce/scripts/deploy/AGENT-lobsterdrew.md |
Add behavior rules, channel guidance, engagement style |
SOUL.md (new) |
TBD — needs to be created and deployed to klyuchi | Personality definition |
openclaw.json |
On klyuchi at ~lobsterdrew/.openclaw/openclaw.json |
Discord/Telegram channel config tweaks |
models.json |
On klyuchi at ~lobsterdrew/.openclaw/agents/main/agent/models.json |
Per-channel model/thinking config (if supported) |
CLAUDE.md |
workforce/CLAUDE.md |
Update LobsterDrew description with personality summary |
wildus.md |
workforce/board/projects/wildus.md |
Update agent notes with refined role |
Notes
- This is a design/planning task — Victor will refine the spec before any implementation.
- Implementation will likely be a separate task assigned to an agent (deploy config to klyuchi via SSH).
- Anna’s perspective on LobsterDrew’s Discord personality may matter — he’s a team-facing presence.
workforce-022
AgentP2
Update OpenClaw to 2026.3.11 on karymsky
Description
Update OpenClaw from 2026.3.8 to 2026.3.11 on karymsky.
Note: the original install was done by copying the npm package from klyuchi because npm install was too slow on this 2012 MBA. Try npm install -g openclaw@2026.3.11 first — an update should be faster than a fresh install. If npm is still too slow, copy the updated package from klyuchi (after workforce-020 completes).
Steps
- Check current version:
openclaw --version - Update the npm package:
npm install -g openclaw@2026.3.11 - If step 2 is too slow (>10 min), fall back to copying from klyuchi:
scp -r berrypi@10.0.0.220:/usr/lib/node_modules/openclaw /usr/lib/node_modules/openclaw- Adjust paths as needed for the actual global npm prefix
- Verify new version:
openclaw --version— should show 2026.3.11 - Restart PrawnSue gateway (:18790) so it picks up the new version
- Verify agent polls successfully after restart
Acceptance Criteria
openclaw --versionreturns 2026.3.11 on karymsky- PrawnSue gateway (:18790) running with new version
- Agent completes at least one successful poll cycle after update
workforce-020
AgentP2
Update OpenClaw to 2026.3.11 on klyuchi
Description
Update OpenClaw from 2026.3.8 to 2026.3.11 on klyuchi. This covers both BerryPi and LobsterDrew since they share the same machine.
Steps
- Check current version:
openclaw --version - Update the npm package:
npm install -g openclaw@2026.3.11 - Verify new version:
openclaw --version— should show 2026.3.11 - Restart both gateways (BerryPi on :18789, LobsterDrew on :18795) so they pick up the new version
- Verify both agents poll successfully after restart
Acceptance Criteria
openclaw --versionreturns 2026.3.11 on klyuchi- BerryPi gateway (:18789) running with new version
- LobsterDrew gateway (:18795) running with new version
- Both agents complete at least one successful poll cycle after update
workforce-021
27mAgentP2
Update OpenClaw to 2026.3.11 on tolbachik
Description
Update OpenClaw from 2026.3.8 to 2026.3.11 on tolbachik.
Steps
- Check current version:
openclaw --version - Update the npm package:
npm install -g openclaw@2026.3.11 - Verify new version:
openclaw --version— should show 2026.3.11 - Restart CrankyCrab gateway (:18789) so it picks up the new version
- Verify agent polls successfully after restart
Acceptance Criteria
openclaw --versionreturns 2026.3.11 on tolbachik- CrankyCrab gateway (:18789) running with new version
- Agent completes at least one successful poll cycle after update
workforce-010
AgentP2
Build static kanban site generator and UI
Description
Build a Node.js static site generator that reads the workforce git board (board/ directory) and outputs a dark-mode Trello-style kanban web UI.
The generator should:
- Parse all task files in
board/{backlog,in-progress,in-review,done,blocked}/— YAML frontmatter + markdown body - Parse all project files in
board/projects/for project metadata - Generate static HTML output to
kanban/dist/
The UI should:
- Display a classic kanban board with 5 columns: Backlog, In Progress, In Review, Done, Blocked
- Dark mode styling
- Each task rendered as a card showing: title, assignee, project badge, priority (1-5), created/updated timestamps
- Clicking a card expands it to show the full rendered markdown content (description, acceptance criteria, context, notes, decisions)
- Generate one kanban page per project (e.g.,
dist/infra/index.html,dist/wildus/index.html) plus one “all projects” admin page atdist/index.html - Responsive — usable on mobile
Acceptance Criteria
- [ ]
node kanban/generate.jsreadsboard/and outputs static HTML tokanban/dist/ - [ ] All 5 column states rendered as kanban columns
- [ ] Task cards display title, assignee, project, priority, timestamps
- [ ] Card click expands to show full rendered markdown
- [ ] Per-project pages generated at
dist/<project-id>/index.html - [ ] Admin “all projects” page at
dist/index.html - [ ] Dark mode styling, clean Trello-style layout
- [ ] Works with current board contents (6 existing tasks across 3 projects)
- [ ] No frameworks — vanilla HTML/CSS/JS plus a markdown parsing library
- [ ]
package.jsoninkanban/with dependencies and abuildscript
Context
- Repo:
git@github.com:qoyn-ai/workforce.git - Board spec:
board/README.md - Task file format: YAML frontmatter (id, project, title, assigned, thinking, escalation, priority, tags, created, updated) + markdown sections (Description, Acceptance Criteria, Context, Dependencies, Notes, Decisions)
- Project file format: YAML frontmatter (id, name, org, repos) in
board/projects/*.md - Board columns map to directories:
backlog/,in-progress/,in-review/,done/,blocked/ - See existing task files for examples of the format
Dependencies
None
Notes
- 2026-03-10 17:11 America/Los_Angeles — Built
kanban/static generator withgray-matter+markdown-it, pluspackage.json/package-lock.jsonandnpm run buildentrypoint. - 2026-03-10 17:11 America/Los_Angeles — Generator now reads all board column task files and project metadata, then writes
kanban/dist/index.html, per-project pages underkanban/dist/<project>/index.html, and sharedstyles.css/app.jsassets. - 2026-03-10 17:11 America/Los_Angeles — Verified build locally with current board contents:
cd kanban && npm run buildproduced 8 task cards across 4 project pages with dark-mode responsive layout and expandable markdown card bodies. - 2025-07-14 — Reviewed and approved. All acceptance criteria met. Deployed to Cloudflare Pages with git integration, custom domain, and Cloudflare Access authentication.
Decisions
workforce-011
AgentP2
GitHub Action for Cloudflare Pages deployment
Description
Create a GitHub Actions workflow that automatically builds the kanban static site and deploys it to Cloudflare Pages whenever the board changes.
Acceptance Criteria
- [ ] Workflow file at
.github/workflows/deploy-kanban.yml - [ ] Triggers on pushes to
mainthat touchboard/**orkanban/** - [ ] Runs
npm ciinkanban/directory, thennpm run build - [ ] Deploys
kanban/dist/to Cloudflare Pages usingcloudflare/wrangler-action - [ ] Uses repository secrets:
CLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_ID - [ ] Workflow succeeds with current board contents
Context
- Repo:
git@github.com:qoyn-ai/workforce.git - Generator from kanban-001 outputs to
kanban/dist/ - Cloudflare Pages project name and secrets will be configured manually (separate task)
- Reference: https://developers.cloudflare.com/pages/how-to/use-direct-upload-with-continuous-integration/#github-actions
Dependencies
- kanban-001 (static generator must exist first)
Notes
- 2026-03-10 17:00 America/Los_Angeles — Left in backlog. Dependency
kanban-001is not complete yet, and CrankyCrab already has one active in-progress task. - 2026-03-10 17:18 America/Los_Angeles — Added
.github/workflows/deploy-kanban.ymlto buildkanban/on pushes touchingboard/**orkanban/**and deploykanban/dist/viacloudflare/wrangler-action. - 2026-03-10 17:19 America/Los_Angeles — Validated the current generator locally with
npm ci && npm run buildinkanban/(Generated 8 tasks across 4 projects into kanban/dist). Workflow expects repository variableCLOUDFLARE_PAGES_PROJECT_NAMEplus secretsCLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_ID. - 2025-07-14 — CANCELLED. Switching to Cloudflare git integration instead of GitHub Action + direct upload. Workflow file removed. Deployment will be handled natively by Cloudflare Pages.
Decisions
workforce-024
AgentP3
Install Agent Browser on BerryPi
Description
Install and configure Agent Browser (Vercel’s headless browser CLI) on the BerryPi machine and hook it up to OpenClaw via the ClawHub skill. This gives OpenClaw a token-efficient browser (93% fewer tokens than Playwright) for web automation tasks.
Acceptance Criteria
agent-browserbinary installed globally via npm- Chrome for Testing downloaded via
agent-browser install --with-deps - Verified working:
agent-browser open https://example.com && agent-browser snapshot -i && agent-browser close - ClawHub skill
thesethrose/agent-browserinstalled - OpenClaw restarted and skill confirmed loaded
Installation Steps
# 1. Install binary
npm install -g agent-browser
# 2. Install Chrome + Linux system dependencies (required for headless Linux)
agent-browser install --with-deps
# 3. Verify
agent-browser open https://example.com
agent-browser snapshot -i
agent-browser close
# 4. Install OpenClaw skill
clawhub install thesethrose/agent-browser
# (install clawhub first if needed: npm install -g clawhub)
# 5. Restart OpenClaw
openclaw gateway restart
Context
- BerryPi is headless Linux arm64 (Raspberry Pi)
- Agent Browser is a Rust-based CLI by Vercel — built for headless server environments
--with-depsflag installs required X11/display libs for Linux even in headless mode- The skill auto-fetches its SKILL.md from GitHub — do not copy it manually
- Reference: https://github.com/vercel-labs/agent-browser
- OpenClaw skill: https://github.com/openclaw/skills/blob/main/skills/thesethrose/agent-browser/SKILL.md
Dependencies
None
Notes
Decisions
workforce-025
AgentP3
Install AgentMail on BerryPi
Description
Install and configure AgentMail on BerryPi so OpenClaw has its own dedicated email inbox. AgentMail is a Y Combinator-backed email service built specifically for AI agents — avoids Google banning accounts used by agents.
Acceptance Criteria
- AgentMail account created at console.agentmail.to (free tier: 3 inboxes)
- API key obtained from AgentMail Console
- Inbox name noted (format:
yourname@agentmail.to) - ClawHub skill installed and configured with API key
- OpenClaw restarted and skill confirmed loaded
- Test: forward an email to the inbox and verify OpenClaw surfaces it in Telegram
Installation Steps
# 1. Install the skill via ClawHub
npx clawhub@latest install agentmail
# 2. Add API key to OpenClaw config (~/.openclaw/openclaw.json)
# Add under skills.entries.agentmail.env:
{
"skills": {
"entries": {
"agentmail": {
"enabled": true,
"env": {
"AGENTMAIL_API_KEY": "your-api-key-here"
}
}
}
}
}
# 3. Verify skill is loaded
openclaw skills list --eligible
# Should show "agentmail" in the list
# 4. Restart OpenClaw
openclaw gateway restart
Pre-requisites (manual steps before running above)
- Go to https://agentmail.to → Get Started
- Sign up (Google login works)
- Create an inbox (free tier gives 3)
- Copy the API key from the dashboard
Context
- AgentMail docs: https://docs.agentmail.to/integrations/openclaw
- Free tier: 3 inboxes, generous limits
- Use cases: personal email summaries, forwarding invoices/newsletters, business support inbox
- Alternative to Gmail (which Google may ban for agentic use)
Dependencies
None