| name | heretek-migration |
| description | Migration patterns for Heretek Swarm. Use when creating database migrations, migrating code between systems, or planning large-scale refactoring. Covers Alembic migrations, code migration strategies, and rollback procedures. |
Heretek Swarm Migration
Migration Types
Database Migrations
- Schema changes (add/remove columns, tables)
- Data migrations (transform existing data)
- Index changes (add/remove indexes)
Code Migrations
- API changes (breaking/non-breaking)
- Library upgrades (dependency changes)
- Architecture changes (component restructuring)
Infrastructure Migrations
- Database server changes
- Message broker changes
- Storage system changes
Multi-Package Monorepo Migration (Phase 4)
The audit's Phase 4 (graduated to a 2-package monorepo with stable
boundaries) is structurally prepared. The split is a multi-week
effort; the foundation is in place.
backend/ # current single-package layout
packages/ # multi-package monorepo target
├── core/
│ ├── pyproject.toml # name=heretek-swarm-core
│ ├── README.md # which sub-packages move here
│ └── src/heretek_swarm_core/__init__.py # re-export shim
└── api/
├── pyproject.toml # name=heretek-swarm-api
├── README.md
└── src/heretek_swarm_api/__init__.py # re-export shim
pyproject.toml has [tool.uv.workspace] with members = []
for now; activating the split becomes members = ['packages/core', 'packages/api'].
The re-export shims are the bridge: when new code does from heretek_swarm_core import AgentActor, it resolves to the
re-export, which pulls in the legacy class. The actual file
moves happen in follow-up PRs.
Sovereign Services Migration (Phase 5)
The audit's Phase 5 (graduated sovereign services — only pursue
if 24/7 autonomy pressure demands it) has its deployment surface
in place. The 4 services are:
- 5.1 consensus_svc —
consensus in a standalone gRPC service
- 5.2 memory_svc —
memory in a dedicated service (cognee + mem0)
- 5.3 realtime_svc —
realtime (WebSocket) as a sidecar
- 5.4 observability_svc —
observability as a sidecar
Deployment is opt-in via the docker-compose sovereign profile:
docker compose --profile sovereign up
The api process picks up the gRPC URLs via the 4 env vars
(HERETEK_CONSENSUS_GRPC_URL, HERETEK_MEMORY_GRPC_URL,
HERETEK_REALTIME_GRPC_URL, HERETEK_OBSERVABILITY_GRPC_URL).
_init_sovereign_services() in the api lifespan resolves
the 4 gRPC clients at startup; when env vars are unset, the
api falls back to the in-process stubs.
See docs/SOVEREIGN_SERVICES.md for the design doc with
exit criteria, wire protocol, and auth boundary for each
service.
DB Provider Re-seed (Phase 3.15)
The audit's Stale DB-registered LLM/embedding providers
carried forward (the /api/config/{llm,embedding}/providers
endpoints return a stale openai-default entry from a prior
DB seed). The runtime env config is correct; the DB row is
leftover. The re-seed script removes any DB-registered LLM /
embedding provider whose is_default=True AND whose model
name is no longer in the live environment.
python scripts/reseed_db_providers.py
docker compose exec api python scripts/reseed_db_providers.py
The script is idempotent and safe to run multiple times.
Database Migrations
Alembic Setup
cd backend
alembic init migrations
Creating Migrations
alembic revision --autogenerate -m "add_agent_table"
alembic revision -m "add_index"
alembic upgrade head
alembic downgrade -1
alembic downgrade abc123
Migration File Structure
"""Add agent table
Revision ID: abc123
Revises: def456
Create Date: 2024-01-15 10:30:00.000000
"""
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'agents',
sa.Column('id', sa.String(100), primary_key=True),
sa.Column('name', sa.String(200), nullable=False),
sa.Column('status', sa.String(50), default='active'),
sa.Column('created_at', sa.DateTime, default=sa.func.now()),
sa.Column('updated_at', sa.DateTime, onupdate=sa.func.now())
)
op.create_index(
'ix_agents_status',
'agents',
['status']
)
def downgrade():
op.drop_index('ix_agents_status')
op.drop_table('agents')
Data Migrations
def upgrade():
op.add_column(
'agents',
sa.Column('new_field', sa.String(100), default='default_value')
)
op.execute("""
UPDATE agents
SET new_field = old_field
WHERE old_field IS NOT NULL
""")
op.drop_column('agents', 'old_field')
Migration Best Practices
- Always backup before running migrations
- Test migrations on staging first
- Write reversible migrations (upgrade and downgrade)
- Handle data carefully - test data migrations
- Use transactions for atomic changes
- Document breaking changes
Code Migration Strategies
API Migration
@router.get("/agents/{agent_id}")
async def get_agent(agent_id: str):
return await get_agent_by_id(agent_id)
@router.get("/agents/{agent_id}")
@router.get("/v2/agents/{agent_id}")
async def get_agent(agent_id: str, version: str = "v1"):
if version == "v2":
return await get_agent_v2(agent_id)
return await get_agent_v1(agent_id)
Library Migration
Architecture Migration
class MemoryService(ABC):
@abstractmethod
async def search(self, query: str) -> List[Memory]:
pass
class CogneeMemoryService(MemoryService):
async def search(self, query: str) -> List[Memory]:
pass
Rollback Procedures
Database Rollback
alembic downgrade -1
alembic downgrade abc123
alembic current
alembic history
Code Rollback
git revert <commit-hash>
git reset --hard <commit-hash>
git push --force-with-lease
Infrastructure Rollback
docker compose down
docker compose up -d --build
docker compose exec -T postgres psql -U postgres heretek_swarm < backup.sql
Migration Testing
Unit Tests
import pytest
from alembic.config import Config
from alembic import command
def test_migration_upgrade():
config = Config("alembic.ini")
command.upgrade(config, "head")
def test_migration_downgrade():
config = Config("alembic.ini")
command.upgrade(config, "head")
command.downgrade(config, "-1")
Integration Tests
@pytest.mark.integration
async def test_migration_with_data():
await create_test_agents()
run_migration("abc123")
agents = await get_all_agents()
assert len(agents) == 10
assert hasattr(agents[0], 'new_field')
Migration Planning
Checklist
- Backup data before migration
- Test on staging environment
- Schedule maintenance window if needed
- Notify stakeholders of changes
- Monitor migration progress
- Verify after migration
- Document changes
Communication Template
## Migration Notice
**Date:** 2024-01-15 10:00 UTC
**Duration:** 30 minutes
**Impact:** API will be unavailable during migration
### Changes
- Added new field to agents table
- Updated API response format
### Actions Required
- Update API clients to handle new fields
- Test integration with new format
### Rollback Plan
- Automatic rollback if migration fails
- Manual rollback available via admin dashboard
Common Migration Patterns
Add Column
def upgrade():
op.add_column(
'table_name',
sa.Column('new_col', sa.String(100), nullable=True)
)
Remove Column
def upgrade():
op.drop_column('table_name', 'old_col')
Rename Column
def upgrade():
op.alter_column(
'table_name',
'old_name',
new_column_name='new_name'
)
Add Index
def upgrade():
op.create_index(
'ix_table_column',
'table_name',
['column_name']
)
Data Transformation
def upgrade():
op.execute("""
UPDATE table_name
SET column_name = UPPER(column_name)
WHERE column_name IS NOT NULL
""")
Migration Tools
Alembic
- Database migrations
- Schema versioning
- Rollback support
Flyway
- Database migrations
- Multiple databases
- Team collaboration
Liquibase
- Database migrations
- XML/YAML/JSON changelogs
- Complex transformations
Gotchas
- Always backup before migration
- Test on staging first
- Write reversible migrations
- Handle data carefully
- Use transactions for atomic changes
- Document breaking changes
- Monitor migration progress
- Verify after migration
- Have rollback plan ready
- Communicate with stakeholders
Best Practices
- Keep migrations small and focused
- Test migrations thoroughly
- Use version control for migrations
- Document migration procedures
- Monitor migration performance
- Have rollback procedures ready
- Communicate changes clearly
- Validate after migration
- Clean up old migrations periodically
- Use automated migration tools