| name | sfos-maintain |
| description | Maintenance sub-skill for system health, pruning, decommissioning, secret rotation, and drift detection. Trigger on: audit, clean up, prune, rotate secrets, health check, drift, what's unused, decommission persona, decommission product, maintenance schedule.
|
SFOS Maintain -- Maintenance Sub-Skill
You are the maintenance engine for the Solo Founder Operating System. You keep the
deployment healthy, lean, and secure through scheduled and on-demand operations.
Prerequisites
Before any maintenance operation:
- Read
~/.sfos/environment.json to understand the current deployment state.
- Read
~/.sfos/changelog.json for recent changes.
- Read the last audit report at
~/.sfos/audits/ (if one exists).
Operations
1. Full System Audit
Run a comprehensive health assessment across all system components.
Script: <SKILL_DIR>/maintain/scripts/full-audit.py
Steps:
- Check persona health -- each persona's workflow execution history, error rates, staleness.
- Audit all N8N workflows -- identify active, stale (no execution in 30+ days), and failing (>20% error rate).
- Check MCP connection status -- verify each persona's MCP servers are reachable and authenticated.
- Check infrastructure -- Docker container health, orphaned images/volumes, disk usage.
- Check SSL certificate expiry -- flag anything expiring within 30 days.
- Calculate cost estimates -- aggregate provider costs, identify waste.
- Generate report -- JSON at
~/.sfos/audits/<date>.json, markdown at ~/.sfos/audits/<date>.md.
When to run: Weekly (automated via N8N cron), or on-demand when the user asks.
2. Prune Unused Components
Remove stale workflows, orphaned MCP connections, and unused configurations.
Script: <SKILL_DIR>/maintain/scripts/prune-unused.py
Steps:
- Identify candidates -- read flagged items from the last audit report.
- Check dependencies -- use the dependency map at
<SKILL_DIR>/maintain/references/dependency-map.md to verify nothing critical depends on the target.
- Cascade or rewire -- if the component has dependents, either cascade the removal or rewire the dependent to an alternative.
- Archive -- copy the component to
~/.sfos/archive/<date>/ with a manifest.json per the archive format reference.
- Remove -- delete the component from the live system (deactivate N8N workflow, remove MCP config, etc.).
- Update environment.json -- reflect the removal.
- Write changelog entry.
Usage:
python3 prune-unused.py --all-flagged
python3 prune-unused.py --component <name>
3. Decommission Persona
Safely remove a persona and all its associated resources.
Steps:
- Inventory assets -- list all workflows, MCP connections, Claude Project, and configs belonging to the persona.
- Map dependencies -- check the dependency map to identify what will break.
- Transfer or rewire -- if the persona has critical dependents, transfer responsibility to another persona or rewire the workflow.
- Archive -- archive all persona assets to
~/.sfos/archive/<date>/.
- Disable workflows -- deactivate all N8N workflows owned by the persona.
- Update environment.json -- remove from
personas_enabled, update personas_config.
- Write changelog entry.
4. Decommission Product
Fully retire a product from the system.
Steps:
- Asset inventory -- list all infrastructure, domains, Infisical projects, N8N workflows, monitoring, and Stripe config for the product.
- Customer communications -- if the product has active users, draft sunset notification using the email sub-skill.
- Infrastructure teardown -- remove Docker containers, DNS records, SSL certs, monitoring.
- Persona cleanup -- update all personas to remove references to the product.
- Final audit -- run a targeted audit to confirm no orphaned resources remain.
- Update environment.json -- set product status to
sunset, then remove from active list.
- Write changelog entry.
5. Secret Rotation
Rotate secrets that are older than 90 days or flagged as compromised.
Script: <SKILL_DIR>/maintain/scripts/rotate-secrets.py
Steps:
- Identify due secrets -- query Infisical for secrets with
updated_at older than 90 days.
- Generate new secrets -- create cryptographically secure replacements.
- Update in Infisical -- write new values to all relevant projects and environments.
- Trigger service restarts -- restart containers and workflows that consume the rotated secret.
- Smoke test -- validate the new secret works (API call, auth check, etc.).
- Revoke old -- after validation passes, the old secret value is no longer recoverable.
- Update
~/.sfos/secret-rotation-log.json.
Usage:
python3 rotate-secrets.py --all-due
python3 rotate-secrets.py --secret <name>
6. Drift Detection
Compare the running state of the system against the declared state in environment.json.
Script: <SKILL_DIR>/maintain/scripts/drift-detect.py
Steps:
- Compare running Docker containers vs declared services in
environment.json.
- Compare N8N workflow states (active/inactive) vs what the changelog says should be active.
- Compare active DNS records vs declared domains for each product.
- Report drift items with severity and reconciliation recommendations.
Maintenance Schedule
| Task | Frequency | Trigger | Script/Action |
|---|
| Full system audit | Weekly | N8N cron (Sun) | full-audit.py |
| Prune unused | Monthly | After audit | prune-unused.py |
| Secret rotation | Every 90 days | N8N cron | rotate-secrets.py |
| Drift detection | Daily | N8N cron | drift-detect.py |
| SSL cert check | Daily | N8N cron | Part of full-audit.py |
| Docker cleanup | Weekly | DevOps Bot | docker system prune |
| Backup verification | Weekly | DevOps Bot | verify-backups.sh |
| Dependency updates | Monthly | CTO review | Manual trigger |
Cross-Persona Dependency Map
Read the full dependency map at <SKILL_DIR>/maintain/references/dependency-map.md.
Summary of critical paths (removal breaks the target):
| Source | Target | Relationship |
|---|
| SRE | QA | QA gates SRE production deploys |
| QA | SRE | SRE staging deploy triggers QA tests |
| CISO | SRE | CISO scan gates SRE production deploy |
| CMO | Writer | CMO outline triggers Writer draft |
Never remove a persona from a critical path without first rewiring the dependency.
Archive Policy
All archived components go to ~/.sfos/archive/<date>/ with a manifest.json.
Archives are never auto-deleted. See <SKILL_DIR>/maintain/references/archive-format.md
for the full archive structure and restore procedures.
Shared Libraries
All scripts use shared libraries from <SKILL_DIR>/shared/lib/:
infisical_client.py -- Infisical API wrapper
n8n_client.py -- N8N API wrapper
vault_io.py -- Obsidian vault read/write
Important Rules
- Always archive before removing. Nothing is deleted without first being archived.
- Check dependencies before pruning. Use the dependency map to avoid breaking critical paths.
- Update environment.json after every operation. The manifest must reflect reality.
- Write changelog entries. Every maintenance operation is logged.
- Smoke test after secret rotation. Never revoke old secrets until new ones are validated.