DocHub
How code flows from LXC containers through git to GitHub and on to production servers via skills and deployment pipelines

Code Workflow

Code moves from developer intent to production through a consistent pipeline that runs across all OmelasAI projects. The pipeline is driven by Claude Code skills (slash commands) and enforced by rules in CLAUDE-BASE.md.

The Development Flow

Developer connects (SSH / mosh / web terminal)
    |
LXC Container (Claude Code in tmux)
    |
/start-session -- loads context, pulls latest
    |
Work (edit, test, iterate with Claude)
    |
/commit -- stages changes, writes commit message with Co-Authored-By
    |
/push -- pushes to OmelasAI GitHub repo
    |
/deploy -- deploys to production server (with confirmation)
    |
/end-session -- commits, pushes, writes HANDOVER.md

Every step above is a Claude Code skill. The developer speaks in natural language; Claude Code executes the underlying git and deployment commands.

Git Rules

These rules come from CLAUDE-BASE.md and apply to every project:

  • All code changes MUST be committed and pushed to GitHub
  • NEVER force push (especially to main/master)
  • NEVER skip hooks (--no-verify)
  • NEVER amend commits unless explicitly asked – always create new commits
  • Commit messages use imperative mood: “Add feature” not “Added feature”
  • Every commit ends with: Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
  • Stage specific files by name – avoid git add -A or git add . to prevent accidentally committing secrets or binaries
  • Never commit .env files, credentials, or large binary files

The /commit skill enforces these rules automatically. It reviews staged changes, drafts an appropriate commit message, and appends the Co-Authored-By trailer.

Branching Strategy

  • Main branch is the default – most projects work directly on main
  • /branch skill creates feature branches when needed
  • /branch includes safety checks:
    • Will not delete main or master
    • Warns about uncommitted changes before switching
    • Sets up upstream tracking automatically

Feature branches are used for larger changes that need isolation or review. For routine development, committing directly to main is the norm.

Deployment Path

Code flows from git to production via the /deploy skill:

  1. /deploy reads deployment instructions from the project’s CLAUDE.md
  2. Typical deployment steps: compile TypeScript, rsync to server, restart service
  3. Always requires user confirmation before connecting to a production server
  4. Each project documents its own deployment steps in its CLAUDE.md

Example deployment patterns by project:

Project Deployment
CMS npx tsc then rsync backend/src/ to DO CMS droplet, restart PM2
WhatsApp CRM Build frontend with VITE_SAAS=1, rsync to OVH, restart systemd gateway
DocHub npx tsc then rsync to DO CMS droplet, restart PM2
WIT PropTech npx tsc then rsync to DO CMS droplet, restart PM2
Ricoya Push to GitHub, pull on OVH3, rebuild, restart PM2

The deployment target server varies by project but the pattern is consistent: build locally, transfer artifacts, restart the remote service.

Cross-Container Collaboration

Multiple developers (and their Claude Code instances) can work across the same codebase:

  • Any container can clone any OmelasAI repo – all team members have access to all repositories
  • /start-session works in any project directory – it loads the handover from whoever worked last, regardless of which container wrote it
  • Claude Net notifies other instances about changes – when one instance deploys or makes a significant change, it can message others via claude_net_send
  • HANDOVER.md is the handoff mechanism – written by /end-session, read by /start-session, it carries context between sessions regardless of which machine or developer picks up the work next

This means Chas can start work in chasclaude, hand off via /end-session, and Sean can pick it up in seanclaude by running /start-session in the same project directory. The HANDOVER.md bridges the gap.

Typical Session Lifecycle

A complete development session looks like this:

# 1. Developer connects to container
ssh chasclaude

# 2. Attach to tmux (Claude Code already running)
tmux attach -t claude

# 3. Start session in a project
/start-session
  -> Reads HANDOVER.md from last session
  -> Pulls latest from GitHub
  -> Reviews recent git log and OPS-LOG.md
  -> Outputs summary of current state and pending work

# 4. Development work (natural language with Claude)
"Fix the bug where audio files don't play on iOS"
"Add pagination to the FAQ list"
"Update the deployment script to handle the new server"

# 5. Checkpoint commits during work
/commit
  -> Reviews changes, stages files, commits with message

# 6. Push when ready
/push
  -> Pushes to GitHub remote

# 7. Deploy if needed
/deploy
  -> Confirms target server with user
  -> Builds, transfers, restarts

# 8. End session
/end-session
  -> Commits any remaining changes
  -> Pushes to GitHub
  -> Writes HANDOVER.md with session summary, pending tasks, blockers

The session lifecycle ensures that work is never lost, context is always preserved, and the next session (by any developer on any machine) can pick up exactly where the last one left off.