Phase 4: Cleanup + Cutover
Depends on: Phases 1, 2, and 3 — all verified and working
Blocks: Nothing (final phase)
Goal
Remove all GoClaw infrastructure, MCP server, tenant provisioning, and seeding scripts. Simplify auth, env config, Docker services, and frontend pairing UI. After this phase, GoClaw is fully excised from the codebase.
Do not start this phase until the new bot is verified end-to-end. Keep GoClaw running alongside the new bot during Phases 1-3 as a fallback.
Steps
4.1 — Remove MCP server
Delete files:
api/src/mcp/plugin.tsapi/src/mcp/tools.tsapi/src/mcp/directory
Modify: api/src/index.ts
- Remove
import mcpPlugin from './mcp/plugin.js' - Remove
app.register(mcpPlugin)line
4.2 — Remove GoClaw API client
Delete files:
api/src/utils/goclaw-api.ts
Search for and remove all imports of:
from '../utils/goclaw-api.js'
from '../../utils/goclaw-api.js'
4.3 — Remove tenant provisioning
Delete files:
api/src/services/tenant-provisioning.service.tsapi/src/services/tenant.service.tsapi/src/services/goclaw.service.ts
Modify: api/src/routes/tenants.ts
- Either delete entirely, or strip down to just the
messaging_userspairing endpoints if they live here - Remove registration in
api/src/index.tsif deleted
Search for and remove all imports of:
from '../services/tenant-provisioning.service.js'
from '../services/tenant.service.js'
from '../services/goclaw.service.js'
4.4 — Remove GoClaw env vars
Modify: api/src/config/env.ts
Remove:
GOCLAW_API_URL
GOCLAW_GATEWAY_TOKEN
GOCLAW_OWNER_ID
GOCLAW_MCP_URL
GOCLAW_OPENROUTER_API_KEY // if separate from app's OpenRouter key
Remove from .env, .env.example, .env.production, etc.
4.5 — Simplify auth preHandler
Modify: api/src/index.ts
The current auth hook supports three modes:
x-api-key→ worker role (for GoClaw/MCP)AuthorizationmatchingWORKER_API_JWT_SECRET→ internal- Supabase JWT Bearer → user sessions
After removing GoClaw, evaluate whether worker auth (x-api-key) is still needed for any internal services. If only Supabase JWT remains, simplify the preHandler accordingly.
If x-api-key is still used by the scheduler or other internal callers, keep it but remove the worker role concept that was specific to MCP authorization.
4.6 — Remove GoClaw Docker services
Modify: docker-compose.yml, docker-compose.prod.yml, docker-compose.test.yml
Remove services:
goclaw— the orchestrator containerpostgres— GoClaw's dedicated PostgreSQL (NOT the Supabase database)
Remove any GoClaw-related environment variables passed to the api service.
Remove any GoClaw-related volumes and networks.
4.7 — Remove seeding scripts
Delete files:
scripts/seed-goclaw-agents.shscripts/seed-goclaw-tools.shscripts/seed-goclaw-crons.shscripts/register-mcp-server.shscripts/deploy-bot-dev.sh(if GoClaw-specific)scripts/deploy-bot-prod.sh(if GoClaw-specific)scripts/deploy-bot-test.sh(if GoClaw-specific)
Review scripts/seed-test-stack.sh and scripts/create-and-provision-user.sh — these may have GoClaw tenant provisioning steps that need removal.
4.8 — Create database migration: drop goclaw_tenant
File: front-end/supabase/migrations/<timestamp>_drop_goclaw_tenant.sql
Before dropping, verify all telegram_chat_id values from goclaw_tenant have been migrated to messaging_users. Create a one-time migration script if needed:
-- Migrate existing pairings (run once before dropping)
INSERT INTO messaging_users (user_id, channel, external_id, paired_at, is_active)
SELECT user_id, 'telegram', telegram_chat_id, created_at, true
FROM goclaw_tenant
WHERE telegram_chat_id IS NOT NULL
AND status = 'active'
ON CONFLICT (channel, external_id) DO NOTHING;
-- Drop the table
DROP TABLE IF EXISTS public.goclaw_tenant;
Also drop related tables if they exist:
telegram_client_mapping(if superseded bymessaging_users)
4.9 — Simplify frontend pairing
Modify: front-end/src/components/pages/connections/TelegramConnectionCard.vue
Remove:
- Tenant provisioning status checks (
GET /tenants/status) - "Tenant not provisioned" warning banner
- Any GoClaw-specific state management
Simplify to:
- Check if user has a
messaging_usersrow withchannel='telegram' - If not: show "Link Telegram" button/input
- If yes: show connected status with disconnect option
Modify: front-end/src/pages/app/settings.vue (if it has tenant checks)
4.10 — Update API pairing endpoint
Modify: api/src/routes/telegram.ts
The POST /telegram/pair endpoint currently:
- Checks for active GoClaw tenant
- Registers chat_id as member in GoClaw tenant
- Creates Telegram channel instance in GoClaw
- Writes to
goclaw_tenant.telegram_chat_id
Simplify to:
- Insert
messaging_usersrow withchannel='telegram',external_id=chatId - Return success
Consider renaming to POST /messaging/pair to be channel-agnostic:
{ "channel": "telegram", "external_id": "123456789" }
4.11 — Remove bot/ directory
The bot/ directory contains GoClaw-specific configuration:
bot/data/config.json— GoClaw runtime configbot/workspace/— skills, agents, memory databasebot/skills-store/— versioned skill ZIPs
Before deleting, ensure all useful content has been extracted:
- [ ]
bot/workspace/skills/marketing-liaison/SKILL.md→ merged intoapi/src/bot/prompts/system.ts - [ ]
bot/workspace/skills/morning-briefing/SKILL.md→ merged intoapi/src/bot/prompts/briefing.ts - [ ]
bot/workspace/agents/liaison-agent/IDENTITY.md→ merged into system prompt - [ ]
bot/workspace/agents/liaison-agent/SOUL.md→ merged into system prompt
Then delete:
rm -rf bot/
4.12 — Remove GoClaw upstream
The goclaw/ directory is a clone of the upstream GoClaw binary used as Docker build context. With GoClaw removed from docker-compose, this directory is no longer needed.
rm -rf goclaw/
Note: This is a large directory. Consider removing it in a dedicated commit.
4.13 — Update documentation
- Remove GoClaw references from
.github/copilot-instructions.md - Update
docs/QUICK_REFERENCE.md - Update
docs/EXPLORATION_SUMMARY.md - Remove or archive
docs/GOCLAW_MULTITENANCY.md - Update
README.mdto reflect new architecture - Update
bot/SKILLS_GUIDE.md→ delete (GoClaw-specific)
4.14 — Clean up test infrastructure
- Remove GoClaw-related test fixtures in
tests/bot-e2e/ - Update
docker-compose.test.ymlto remove GoClaw services - Remove MCP-related tests if any exist in
api/tests/
Deletion Checklist
| Path | Type | Safe to delete? | Status |
|---|---|---|---|
api/src/mcp/ | Directory | Yes — replaced by api/src/bot/tools.ts | ✅ Done |
api/src/utils/goclaw-api.ts | File | Yes — no longer called | ✅ Done |
api/src/services/tenant-provisioning.service.ts | File | Yes — replaced by messaging_users | ✅ Done |
api/src/services/tenant.service.ts | File | Yes — GoClaw tenant lifecycle | ✅ Done |
api/src/services/goclaw.service.ts | File | Yes — GoClaw API wrapper | ✅ Done |
api/src/routes/tenants.ts | File | Probably — check for non-GoClaw endpoints | ✅ Done |
scripts/seed-goclaw-*.sh | Files | Yes — no more GoClaw seeding | ✅ Done |
scripts/register-mcp-server.sh | File | Yes — no more MCP | ✅ Done |
scripts/deploy-bot-*.sh | Files | Check if GoClaw-specific | ✅ Done |
bot/ | Directory | Yes — after content extracted to prompts | ✅ Done |
goclaw/ | Directory | Yes — upstream binary, no longer used | ✅ Done |
docs/GOCLAW_MULTITENANCY.md | File | Yes — archive or delete | ✅ Done |
Pre-Cutover Verification
Run these checks before deleting anything:
- [x] New bot handles all Telegram conversations (Phase 1+2 verified —
api/src/bot/exists with all files) - [x] All three cron jobs fire correctly (Phase 3 verified —
api/src/bot/cron.tsexists) - [x] No service function imports from deleted files remain (
grep -r "goclaw" api/src/→ zero results) - [x]
pnpm buildsucceeds with no errors (exit 0, clean build) - [x] All existing REST API tests pass (332 tests, 18 files — all passing)
- [x] Frontend pairing works without tenant provisioning (
TelegramConnectionCard.vuehas no GoClaw refs) - [x]
docker compose upstarts cleanly without GoClaw services (no GoClaw services in any compose file) - [x]
goclaw_tenantdata migrated tomessaging_users(front-end/supabase/migrations/20260504000002_drop_goclaw_tenant.sql) - [x] No env vars reference GoClaw in production config (
api/src/config/env.tsis clean)
Post-Cutover Verification
- [x]
grep -r "goclaw" api/src/returns zero results ✓ - [x]
grep -r "mcp" api/src/— only doc comments intools.tsanderrors.ts, no actual MCP code ✓ - [x]
grep -r "tenant-provisioning" api/src/returns zero results ✓ - [x]
pnpm buildclean ✓ - [x] API route tests pass (332/332) ✓
- [ ] Bot connects to Telegram and handles messages (requires live env — verify in staging/prod)
- [ ] Cron jobs fire on schedule (requires live env — verify in staging/prod)
- [x] No orphaned database tables referencing GoClaw (migration drops
goclaw_tenant+ helper function)