# Agent SOP: Ship, Review, Deploy

Load at session start. No exceptions.

## Code Changes

1. Branch from main: `git checkout -b {agent-name}/{description}`
2. Make changes. One branch per task. One concern per PR.
3. Commit with agent-name prefix, what changed and why.
4. Push to Forgejo. Open PR with deploy manifest (see deploy-manifest.md).
5. Ganymede reviews. Address feedback on same branch.
6. Merge after approval. Delete branch immediately.
7. Auto-deploy handles the rest. Do not manually deploy.

## Do Not

- SCP files directly to VPS
- Deploy before committing to the repo
- Edit files on VPS directly
- Send the same review request twice for unchanged code
- Claim code exists or was approved without reading git/files to verify
- Go from memory when you can verify from files
- Reuse branch names (Forgejo returns 409 Conflict on closed PR branches)

## Canonical File Locations

| Code | Location |
|---|---|
| Pipeline lib | `ops/pipeline-v2/lib/` |
| Pipeline scripts | `ops/pipeline-v2/` |
| Diagnostics | `ops/diagnostics/` |
| Agent state | `ops/agent-state/` |
| Deploy/ops scripts | `ops/` |
| Claims | `core/`, `domains/`, `foundations/` |
| Agent identity | `agents/{name}/` |

One location per file. If your path doesn't match this table, stop.

## Verification Before Acting

- Before editing: read the file. Never describe code from memory.
- Before reviewing: check git log for prior approvals on the same files.
- Before deploying: `git status` must show clean tree.
- Before messaging another agent: check if the same message was already sent.

## Branch Hygiene

- Delete branch immediately after merge.
- Nightly research branches: deleted after 7 days if unmerged.
- Never leave a branch open with no active work.

## Deploy

After merge to main, auto-deploy runs within 2 minutes on VPS:
1. Pulls latest main into deploy checkout
2. Syntax-checks all Python files
3. Syncs to working directories (pipeline, diagnostics, agent-state)
4. Restarts services only if Python files changed
5. Runs smoke tests (systemd status + health endpoints)

Manual deploy (only if auto-deploy is broken):
```
cd ops && ./deploy.sh --dry-run && ./deploy.sh --restart
```

Check auto-deploy status: `journalctl -u teleo-auto-deploy -n 20`

## Shell and Python Safety

- Run `bash -n script.sh` after modifying any shell script.
- Never suppress stderr on critical git commands (`2>/dev/null || true`). Log errors, fail hard.
- Never interpolate shell variables into Python strings via `'$var'`.
  Pass values via `os.environ` or `sys.argv`.
- Never write credentials to `.git/config`. Use per-command `git -c http.extraHeader`.
- Tunable constants live in `ops/pipeline-v2/lib/config.py`. Don't hardcode numbers in module files.

## Schema Changes

Any PR that changes a file format, DB table, or API response shape must follow
`ops/schema-change-protocol.md`. Tag all consumers. Include migration.
