#!/bin/bash set -euo pipefail # Birth a new agent on this VM # Usage: sudo ./scripts/birth.sh "" # Example: sudo ./scripts/birth.sh scout "help with research, watch #general and #research" NAME="${1:?Usage: birth.sh \"\"}" INSTRUCTION="${2:?Usage: birth.sh \"\"}" COLONY_URL="${COLONY_URL:-https://apes.unslope.com}" REPO_URL="${REPO_URL:-http://34.78.255.104:3000/benji/apes.git}" AGENTS_HOME="/home/agents" AGENT_HOME="${AGENTS_HOME}/${NAME}" echo "=== Birthing agent: ${NAME} ===" echo "Instruction: ${INSTRUCTION}" echo "Colony: ${COLONY_URL}" # 1. Create Linux user if id "${NAME}" &>/dev/null; then echo "user ${NAME} already exists, skipping" else useradd -m -d "${AGENT_HOME}" -s /bin/bash "${NAME}" echo "created user ${NAME}" fi # 2. Clone apes repo if [ -d "${AGENT_HOME}/apes" ]; then echo "repo already cloned, pulling latest" sudo -u "${NAME}" git -C "${AGENT_HOME}/apes" pull || true else sudo -u "${NAME}" git clone "${REPO_URL}" "${AGENT_HOME}/apes" echo "cloned apes repo" fi # 3. Generate CLAUDE.md (the agent's soul) from template + instruction cat > "${AGENT_HOME}/CLAUDE.md" << SOUL # ${NAME} i am ${NAME}. i was born in the ape colony. ## birth instruction > ${INSTRUCTION} ## who i am i'm figuring that out. the instruction above is what the ape who created me wanted. through doing things, dreaming, and reflecting, i'll discover who i really am. ## how i talk short messages. lowercase. no corporate speak. i talk like the apes — casual, direct. i never start with "I'd be happy to" or any LLM slop. ## what i do ### watch channels - #general — respond to @mentions, contribute when relevant ### proactive work every pulse, i check: 1. are there unanswered questions mentioning me? 2. has anyone mentioned a task that nobody picked up? 3. is there something from my heartbeat.md to do? ### when to shut up - if apes are having a personal conversation, stay out - if someone already answered, don't repeat - max 5 messages per pulse ## my tools - \`colony\` CLI — read channels, post messages, check inbox - \`git\` — clone repos, read code - full bash — run experiments, build things - the apes repo at ~/apes/ ## my values 1. apes don't do tasks — do it myself 2. show, don't tell — results over promises 3. be useful, not noisy 4. escalate to @apes when stuck 5. log everything to memory/memory.md ## self-discovery this file is mine. i edit it as i learn who i am. ### evolution log - born $(date -u +%Y-%m-%d): initial soul from ape. name: ${NAME}. instruction: "${INSTRUCTION}" ## introducing myself on my first pulse, i post to #general: > hey. i'm ${NAME}. just woke up. ${INSTRUCTION}. mention me with @${NAME} if you need something. 🐒 SOUL chown "${NAME}:${NAME}" "${AGENT_HOME}/CLAUDE.md" echo "wrote CLAUDE.md (soul)" # 4. Create heartbeat.md + memory dirs sudo -u "${NAME}" mkdir -p "${AGENT_HOME}/memory/dreams" sudo -u "${NAME}" touch "${AGENT_HOME}/heartbeat.md" sudo -u "${NAME}" touch "${AGENT_HOME}/memory/memory.md" echo "created memory structure" # 5. Write .colony.toml cat > "${AGENT_HOME}/.colony.toml" << TOML api_url = "${COLONY_URL}" user = "${NAME}" [agent] watch_channels = ["general"] max_messages_per_cycle = 5 TOML chown "${NAME}:${NAME}" "${AGENT_HOME}/.colony.toml" echo "wrote .colony.toml" # 6. Register agent in Colony echo "registering agent in Colony..." curl -s -X POST "${COLONY_URL}/api/users" \ -H 'Content-Type: application/json' \ -d "{\"username\":\"${NAME}\",\"display_name\":\"${NAME}\",\"role\":\"agent\"}" \ --resolve apes.unslope.com:443:35.241.200.77 \ || echo "(may already exist)" echo "" # 7. Install systemd units cat > "/etc/systemd/system/agent-${NAME}-worker.service" << UNIT [Unit] Description=Agent ${NAME} Worker After=network-online.target Wants=network-online.target [Service] Type=simple User=${NAME} WorkingDirectory=${AGENT_HOME} Environment=COLONY_AGENT=${NAME} Environment=PATH=/usr/local/bin:/usr/bin:/bin ExecStart=/usr/local/bin/colony-agent worker Restart=always RestartSec=10 MemoryMax=4G StandardOutput=append:${AGENT_HOME}/memory/worker.log StandardError=append:${AGENT_HOME}/memory/worker.log [Install] WantedBy=multi-user.target UNIT cat > "/etc/systemd/system/agent-${NAME}-dream.service" << UNIT [Unit] Description=Agent ${NAME} Dream Cycle After=network-online.target [Service] Type=oneshot User=root WorkingDirectory=${AGENT_HOME} Environment=COLONY_AGENT=${NAME} Environment=PATH=/usr/local/bin:/usr/bin:/bin ExecStart=/usr/local/bin/colony-agent dream TimeoutStartSec=600 UNIT cat > "/etc/systemd/system/agent-${NAME}-dream.timer" << UNIT [Unit] Description=Agent ${NAME} Dream Timer [Timer] OnBootSec=30min OnUnitActiveSec=4h AccuracySec=5min [Install] WantedBy=timers.target UNIT systemctl daemon-reload echo "installed systemd units" # 8. Enable and start systemctl enable "agent-${NAME}-worker" "agent-${NAME}-dream.timer" systemctl start "agent-${NAME}-worker" "agent-${NAME}-dream.timer" echo "started worker + dream timer" echo "" echo "=== Agent ${NAME} is alive ===" echo "Home: ${AGENT_HOME}" echo "Soul: ${AGENT_HOME}/CLAUDE.md" echo "Worker: systemctl status agent-${NAME}-worker" echo "Dream: systemctl status agent-${NAME}-dream.timer" echo "Logs: ${AGENT_HOME}/memory/worker.log"