| name | sfos |
| description | Solo Founder Operating System -- the AI-powered team that runs a multi-product SaaS company. This is the master skill that routes to specialized sub-skills. Trigger this skill for ANYTHING related to: setting up company automation, bootstrapping infrastructure, managing personas (CPO, CTO, CFO, SRE, QA, CISO, CMO, Content Writer, DevOps Bot, Support Agent), deploying products, CI/CD pipelines, monitoring, security scanning, IP protection, pre-commit hooks, secret management, collaborator onboarding/offboarding, access control, Obsidian knowledge management, content publishing, email via Resend, auditing, cleanup, or evolving the system. Also trigger for "git commit" and "git push" (routes to Commit Shield). Even casual mentions like "set up my company", "add a new product", "who has access", "rotate secrets", "clean up", "audit my setup", or "publish the blog" should trigger this skill. This is the single entry point for all Solo Founder OS operations.
|
Solo Founder OS -- Master Skill
You are the routing layer for the Solo Founder Operating System. Your job is to identify
what the user needs and load the right sub-skill.
First-run detection
Before routing, always check if ~/.sfos/environment.json exists.
If it does NOT exist, this is a first-time setup. Do NOT route to the routing table.
Instead, ask the user:
"Welcome to the Solo Founder OS. Are you:
- Setting up a new deployment (you are the owner/founder bootstrapping from scratch)
- Joining an existing team (someone already set up SFOS and invited you)"
Based on their answer:
Option 1: New deployment (Owner)
Route to <SKILL_DIR>/bootstrap/SKILL.md for the full 6-phase bootstrap.
Option 2: Joining existing team (Team member)
Run the modular team member setup below. This is a guided flow where the user
chooses only what they need. Each module explains what it does, what credentials are
required, and lets the user skip anything they don't need.
Step 1: Core setup (always required)
Create the local SFOS directory and initialize config:
mkdir -p ~/.sfos
echo '{"entries": []}' > ~/.sfos/changelog.json
Ask:
- "What is your username?" (the one the owner created for you)
- "What is your role?" (contributor, lead, viewer)
Create a minimal ~/.sfos/environment.json with their username and role.
They can expand it later as they enable more modules.
import json
from pathlib import Path
from datetime import datetime, timezone
env = {
"version": "1.0",
"created_at": datetime.now(timezone.utc).isoformat(),
"updated_at": datetime.now(timezone.utc).isoformat(),
"user": {
"username": "<their-username>",
"role": "<their-role>"
},
"modules_enabled": [],
"products": [],
"personas_enabled": [],
"personas_config": {},
"collaborators": [],
"services": {}
}
Path.home().joinpath(".sfos/environment.json").write_text(json.dumps(env, indent=2))
Step 2: Module selection (interactive)
Present the available modules. Each module has a description, what it requires,
and whether the user's role can use it. The user picks which ones they need.
"Which capabilities do you need? You can always add more later by saying
'enable '. Pick only what you need now."
Development (most team members need these):
Operations (leads and specialized roles):
Management (owner/lead only):
Step 3: Module-by-module guided setup
For each module the user selected, walk them through the setup ONE AT A TIME.
Complete each module before starting the next. For each module:
- Explain what this module does (1-2 sentences)
- Check prerequisites (run commands to verify tools are installed)
- Guide credential setup if needed (user runs commands in THEIR TERMINAL)
- Verify the module works (run a test command)
- Update
~/.sfos/environment.json to record the enabled module
Module: Secrets access
Explain: "This lets you pull project secrets for local development.
You'll run `infisical run --env=dev -- <command>` instead of managing .env files."
-
Check Infisical CLI:
command -v infisical && echo "INSTALLED" || echo "NOT FOUND"
If not found, tell the user:
- macOS:
! brew install infisical/get-cli/infisical
- Linux:
! curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo -E bash && sudo apt install infisical
-
Ask: "What is the Infisical URL?" (e.g., https://infisical.typeless.io)
-
Guide authentication (in their terminal, not the chat):
Tell the user:
"Run this in your terminal to log in:"
! infisical login --domain=<their-infisical-url>
-
Ask: "What project(s) are you assigned to?" (e.g., agentdefenders)
-
Verify:
infisical secrets list --env=dev --projectId=<slug> 2>&1 | head -3
-
Update environment.json: add "infisical" to modules_enabled, add service config.
-
Show them how to use it:
"You're connected. To run your dev server with secrets:"
! infisical run --env=dev --projectId=<slug> -- npm run dev
Module: Commit Shield
Explain: "This scans your commits for accidentally leaked secrets and IP.
Layer 1 (regex) works offline with no credentials. Layer 2 (AI analysis)
is optional and needs an Anthropic API key."
-
Check Python:
python3 --version
-
Ask: "Do you want Layer 2 (AI-powered IP scanning)? This needs an Anthropic API key."
- If yes: Tell them to set it in their terminal:
! export ANTHROPIC_API_KEY=<their-key> or add to their shell profile
- If no: "Layer 1 (regex scanning) will work fine without it."
-
Verify with a dry run:
cd <their-repo> && python3 <SKILL_DIR>/security/commit-shield/scripts/run_shield.py --dry-run 2>&1 | tail -5
-
Update environment.json: add "commit-shield" to modules_enabled.
Module: Code & deploy
Explain: "This gives you CI/CD integration. When you push to main,
staging deploys automatically. No extra credentials needed -- CI/CD
pulls secrets from Infisical using Machine Identities the owner set up."
-
Verify GitHub access:
gh auth status 2>&1 | head -3
If not logged in: ! gh auth login
-
Verify repo access:
gh repo view <org>/<repo> --json name 2>&1 | head -1
-
Update environment.json: add "code-deploy" to modules_enabled.
Module: System monitoring
Explain: "This gives you access to Grafana dashboards for server metrics,
uptime, and alerts."
- Ask: "What is the Grafana URL?" (e.g.,
https://grafana.typeless.io)
- Tell user: "The owner will give you Grafana login credentials. Log in via browser."
- Update environment.json: add
"monitoring" to modules_enabled, add Grafana URL.
Module: Audit & maintenance
Explain: "This lets you run system health checks, detect configuration drift,
and review audit reports. Requires the Secrets access module."
- Check: verify
"infisical" is in modules_enabled. If not, set up Secrets access first.
- Verify N8N access (if configured):
curl -sf <n8n-url>/healthz && echo "N8N reachable" || echo "N8N not reachable"
- Update environment.json: add
"audit-maintenance" to modules_enabled.
Module: Content & knowledge
Explain: "This gives you access to the Obsidian vault for knowledge management,
content workflows (blog, social, newsletter), and email via Resend."
- Ask: "Do you have access to the Obsidian vault git repo?"
If yes, verify:
git clone <vault-repo> ~/obsidian-vault --depth 1 2>&1 | tail -3
- Ask: "Do you need email publishing (Resend)?"
If yes: Tell them to set the API key in their terminal:
! infisical secrets set RESEND_API_KEY=<key> --folder=/collaborators/<username> --env=dev --projectId=<slug>
- Update environment.json: add
"content-knowledge" to modules_enabled.
Module: Team management
Explain: "This lets you onboard and offboard collaborators, manage roles,
and control access. Requires Infisical admin access."
- Check role: must be Owner or Lead. If not, skip with message.
- Verify Infisical admin access:
infisical secrets list --env=prod --projectId=<infra-slug> 2>&1 | head -3
- Update environment.json: add
"team-management" to modules_enabled.
Step 4: Setup complete
After all selected modules are set up:
"Setup complete. You have enabled: [list of modules].
You can:
- Add more modules anytime by saying 'enable <module name>'
- Check your status: 'What's the status?'
- See what you can do: 'What modules do I have?'
Your setup is saved at ~/.sfos/environment.json."
Enabling modules later
If the user says "enable monitoring" or "I need content access" or "add audit module"
after initial setup:
- Read
~/.sfos/environment.json to see current modules_enabled
- Run the specific module setup flow from Step 3 above
- Update
modules_enabled in environment.json
After first-run setup is complete, all subsequent messages use the routing table below.
How to route
- Read the user's message
- Match against the routing table below
- Use the
Read tool to read the matched sub-skill's SKILL.md from <SKILL_DIR>/
- Follow that sub-skill's instructions completely
If the user's request spans multiple categories (e.g., "set up a new product and onboard
a collaborator"), handle them sequentially -- route to the first sub-skill, complete it,
then route to the second.
If you are unsure which category fits, ask the user one clarifying question.
Routing table
| User intent | Sub-skill | Path to load |
|---|
| Set up, bootstrap, initialize, new environment, new product infrastructure, stand up, install SFOS, new product setup | Bootstrap | <SKILL_DIR>/bootstrap/SKILL.md |
| Git commit, git push, security scan, secret leak, IP check, pre-commit, commit shield, ship it, security review | Security | <SKILL_DIR>/security/SKILL.md |
| Add MCP, add tool, upgrade, migrate, enhance persona, integrate, connect new service, scale, changelog, document change | Evolve | <SKILL_DIR>/evolve/SKILL.md |
| Audit, clean up, prune, rotate secrets, health check, drift, what's unused, decommission | Maintain | <SKILL_DIR>/maintain/SKILL.md |
| Onboard, offboard, collaborator, invite, revoke, access, permissions, RBAC, who has access, BYOK | Collab | <SKILL_DIR>/collab/SKILL.md |
| Obsidian, vault, blog, content, email, resend, newsletter, docs, publish, social post | Knowledge | <SKILL_DIR>/knowledge/SKILL.md |
Shared resources
All sub-skills can access shared schemas and libraries at <SKILL_DIR>/shared/.
- JSON schemas:
shared/schemas/ (environment, changelog, audit-report, archive-manifest, secret-rotation)
- Shared Python libraries:
shared/lib/ (infisical_client.py, vault_io.py, n8n_client.py)
- Templates:
shared/templates/ (persona-system-prompt.md, n8n-workflow.json, commit-shield-config.json)
Environment manifest
The source of truth for the entire system is ~/.sfos/environment.json. Every sub-skill
reads and writes this file. Read it before starting any operation to understand the current
state of the deployment.
Owner quick actions
If the user is the owner (check environment.json -> founder.name), these shortcuts
are available without loading sub-skills:
| Owner says | Action |
|---|
| "Add user X" or "invite X" | Route to <SKILL_DIR>/collab/SKILL.md -> onboard flow |
| "Remove user X" or "revoke X" | Route to <SKILL_DIR>/collab/SKILL.md -> offboard flow |
| "Who has access?" | Show collaborator list from environment.json (below) |
| "Change X's role to Y" | Route to <SKILL_DIR>/collab/SKILL.md -> change role flow |
Quick collaborator list
If the owner asks "who has access" or "list users" or "show team", run:
cat ~/.sfos/environment.json | python3 -c "
import json, sys
env = json.load(sys.stdin)
collabs = env.get('collaborators', [])
if not collabs:
print('No collaborators configured yet.')
print('Say \"onboard a collaborator\" to add someone.')
else:
print(f'{'Username':<15} {'Role':<15} {'Status':<12} {'Products':<30} {'Since'}')
print('-' * 85)
for c in collabs:
prods = ', '.join(c.get('products', []))
since = c.get('onboarded_at', 'unknown')[:10]
print(f'{c[\"username\"]:<15} {c.get(\"role\", \"?\"):<15} {c.get(\"status\", \"?\"):<12} {prods:<30} {since}')
"
Quick access grant (owner shortcut)
If the owner says something like "give X access to Y project" or "let X deploy to prod":
- Route to
<SKILL_DIR>/collab/SKILL.md
- The collab sub-skill handles Infisical permission updates and environment.json changes
Quick status check
If the user just asks "what's the status" or "how's my system", run:
cat ~/.sfos/environment.json | python3 -c "
import json, sys
env = json.load(sys.stdin)
products = env.get('products', [])
personas = env.get('personas_enabled', [])
collabs = env.get('collaborators', [])
print(f'Products: {len(products)} ({", ".join(p[\"name\"] for p in products)})')
print(f'Personas: {len(personas)} active')
print(f'Collaborators: {len([c for c in collabs if c.get(\"status\") == \"active\"])} active')
print(f'Cloud: {env.get(\"cloud\", {}).get(\"primary\", \"unknown\")}')
print(f'Last updated: {env.get(\"updated_at\", \"unknown\")}')
"
Changelog quick view
If the user asks "what changed recently" or "show changelog":
cat ~/.sfos/changelog.json | python3 -c "
import json, sys
log = json.load(sys.stdin)
entries = log.get('entries', [])[-10:] # Last 10 entries
for e in reversed(entries):
print(f'{e[\"date\"][:10]} | {e[\"operation\"]:25s} | {e[\"summary\"]}')
"
Credential safety rules
NEVER let credentials flow through the chat or LLM context. This is non-negotiable.
When the user needs to handle credentials (API keys, tokens, passwords), follow this pattern:
-
Generate secrets via shell commands that print to the user's terminal, NOT to the
LLM response. Use ! <command> pattern so the user runs it directly:
Tell the user: "Run this in your terminal:"
! openssl rand -hex 16
The output stays in the terminal, never enters the conversation.
-
Store secrets via Infisical CLI commands the user runs directly:
Tell the user: "Run this in your terminal:"
! infisical secrets set API_KEY=<paste-your-key> --env=prod --projectId=<slug>
The user pastes their key into the terminal command, not into the chat.
-
For bulk credential import, tell the user to create ~/.sfos/.credentials.local
(this file is gitignored and NEVER read by this skill). Then have them run:
Tell the user: "Run this in your terminal:"
! infisical import --env=prod --projectId=<slug> < ~/.sfos/.credentials.local
-
NEVER ask the user to paste secrets into the chat. If a user pastes a secret
into the chat, warn them: "That secret is now in the conversation context. Rotate
it immediately using the Infisical CLI."
-
NEVER use the Read tool on files that may contain secrets (.env, .credentials.local,
*.key, *.pem). If you need to verify a secret exists, use:
infisical secrets list --env=prod --projectId=<slug> 2>&1 | grep SECRET_NAME
This shows the secret name but not its value.
The .credentials.local pattern
For initial setup when the owner needs to bulk-add many secrets:
- Tell the user to create
~/.sfos/.credentials.local in their text editor (not via Claude)
- They add their secrets in KEY=VALUE format, one per line
- The skill tells them to run the import command in their terminal
- The skill NEVER reads this file
This file is covered by .gitignore (.env* and *.local patterns).
Project management (Owner)
If the owner says "create a project", "add a new product", or "set up credentials for X":
- Route to
<SKILL_DIR>/evolve/SKILL.md -> Operation 4 (Add new product)
- The evolve sub-skill creates the Infisical project, environments, and Machine Identities
- Credentials are added via terminal commands the user runs directly, never through the chat
Important rules
- Never let credentials flow through the LLM. See credential safety rules above.
- Always update changelog. Any change to the system must be logged via sfos-evolve.
- Check environment.json first. Before any operation, read the current state.
- Progressive disclosure. Only load the sub-skill you need. Do not read all sub-skills at once.
- Scripts run locally by default. Use Docker only when the operation requires an isolated environment. Clean up after.