Din firul testat in grup: la "Urgent este", "Nu m-a contactat nimeni. Cat mai
dureaza?" si "Tot nimic", Maria trimitea de fiecare data "Caut informatia, revin
imediat...", calcula un embedding pe care il arunca, si raspundea acelasi sablon
("am adaugat si asta la M-..."). La intrebarea "cat mai dureaza" nu raspundea deloc,
iar "urgent" nu schimba nimic nicaieri.
- Completarea se decide INAINTEA confirmarii si a cautarii: raspunsul vine instant,
deci nici promisiune, nici embedding degeaba (~1-2s per mesaj).
- triaj.fel_completare: urgenta / stare / detaliu.
- urgenta -> escaladarea se marcheaza si suportul primeste un mesaj cu URGENT;
- stare -> raspuns cu ce stim (de cat timp asteapta) si reamintire catre echipa,
cel mult una la 15 minute, ca sa nu sune telefonul la fiecare "tot nimic";
- detaliu -> confirmare scurta, cu formularea rotita.
- Peste 30 de minute fara raspuns Maria o spune pe fata si indruma spre telefon
(SUPPORT_PHONE), in loc sa repete ca "echipa vede detaliul".
- Gramatica: "acum 10 minute", nu "acum 10 de minute".
Teste: 99 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4uzvgm7AyJch5WH8QHRhY
LXC 171 - Claude Agent (Development Environment)
Care chatbot e care? Exista trei lucruri numite „Maria", doi boti pe Discord si doua punti WhatsApp legate la acelasi numar. Inainte de a depana, citeste
docs/chatboti-si-punti.md— spune care instanta raspunde de fapt.
Director: proxmox/lxc171-claude-agent/
VMID: 171
IP: 10.0.20.171 (intern) | 100.95.55.51 (Tailscale)
Host Proxmox: pvemini (10.0.20.201)
Rol: Mediu de dezvoltare izolat pentru Claude Code
Scripturi Disponibile
| Script | Descriere |
|---|---|
scripts/start-agent.sh |
Pornește/atașează sesiune tmux "agent" |
scripts/work.sh |
Meniu interactiv pentru workflow complet |
scripts/new-task.sh |
Creează branch nou pentru task |
scripts/finish-task.sh |
Finalizează task (commit + push) |
scripts/reap-orphans.sh |
Curăță procese vscode-server orfane + sesiuni zombie (cron, anti-OOM) |
discord-bridge/ |
Punte Discord → Claude Code: comanzi containerul dintr-un guild privat (README) |
discord-bridge/dashboard/ |
Dashboard de control al punții: stare, restart, orfani, confirmări (README) |
Informații Container
| Parametru | Valoare |
|---|---|
| VMID | 171 |
| Hostname | claude-agent |
| IP intern | 10.0.20.171 |
| IP Tailscale | 100.95.55.51 |
| Host Proxmox | pvemini (10.0.20.201) |
| User | claude |
| Storage | local-zfs (32GB) |
| RAM | 16GB (swap 8GB — vezi nota OOM mai jos) |
| CPU | 4 cores |
Componente Instalate
- Ubuntu 24.04 LTS
- Node.js v20.x (via nvm)
- Claude Code
- tmux
- Git (configurat pentru Gitea)
- Tailscale
Conectare
De pe calculator (rețea internă)
ssh claude@10.0.20.171
De pe telefon/exterior (Tailscale)
ssh claude@100.95.55.51
VS Code Remote SSH
Config în ~/.ssh/config:
Host claude-agent
HostName 10.0.20.171
User claude
Scripturi Workflow
start-agent.sh
Pornește sau se atașează la sesiunea tmux "agent".
~/start-agent.sh
work.sh (recomandat)
Meniu interactiv pentru workflow complet:
- Listează proiectele disponibile în /workspace
- Permite crearea de branch-uri noi
- Continuarea pe branch-uri existente
- Finalizare task (commit + push)
- Vizualizare branch-uri
~/work.sh
new-task.sh
Creează branch nou pentru un task (hardcodat pentru romfastsql).
~/new-task.sh fix/nume-bug
finish-task.sh
Finalizează task-ul curent (commit + push).
~/finish-task.sh
Workflow Complet
De pe telefon (JuiceSSH + Tailscale)
- Conectează-te la
100.95.55.51cu userclaude - Rulează:
~/start-agent.sh # pornește tmux
~/work.sh # meniu interactiv
- Alege proiectul
- Alege acțiunea (task nou / continuă / finalizează)
- Lucrează cu Claude Code
- Când termini:
~/work.sh→ opțiunea 3 (finalizează)
De pe calculator (VS Code)
- VS Code → Remote SSH →
claude-agent - Open Folder →
/workspace/<proiect> - Terminal →
source ~/.nvm/nvm.sh && claude
Structura Directoare pe LXC
/home/claude/
├── .ssh/
│ ├── authorized_keys # Chei SSH pentru acces
│ ├── gitea_ed25519 # Cheie pentru Gitea
│ └── config # Config SSH pentru Gitea
├── .nvm/ # Node Version Manager
├── .claude/
│ └── settings.json # Permisiuni Claude Code
├── .tmux.conf # Configurare tmux
├── start-agent.sh -> /workspace/start-agent.sh
└── work.sh -> /workspace/work.sh
/workspace/
├── start-agent.sh # Script pornire tmux
├── work.sh # Script workflow interactiv
├── new-task.sh # Script creare branch
├── finish-task.sh # Script finalizare task
├── CLAUDE.md # Info agent
├── SETUP-COMPLETE.md # Documentație setup
├── romfastsql/ # Proiect clonat
└── test/ # Alte proiecte
Comenzi tmux Utile
| Comandă | Acțiune |
|---|---|
Ctrl+A, d |
Detașare din sesiune |
Ctrl+A, c |
Fereastră nouă |
Ctrl+A, n |
Fereastră următoare |
Ctrl+A, p |
Fereastră anterioară |
Ctrl+A, [ |
Mod scroll (q pentru ieșire) |
tmux attach -t agent |
Reatașare la sesiune |
tmux ls |
Listare sesiuni |
Git / Gitea
Clonare proiect nou
cd /workspace
git clone git@gitea.romfast.ro:romfast/<nume-repo>.git
Workflow branch-uri
git checkout main
git pull
git checkout -b feature/nume-feature
# ... lucrezi ...
git add .
git commit -m "descriere"
git push -u origin feature/nume-feature
# Creează Pull Request în Gitea
Memorie & OOM (reaping orfane + zram)
Context (incident 2026-06-24)
Containerul a generat OOM-uri repetate, izolate în cgroup-ul /lxc/171 (NU la nivel de
host — host-ul avea memorie liberă). Cauzele combinate:
- Swap fictiv: LXC 171 are
memory: 16384+swap: 8192, dar host-ul pvemini nu avea swap deloc → swap-ul containerului nu era backed de nimic. La atingerea celor 16GB se intra direct în OOM-kill, fără să poată face swap-out. Victimele tipice erau procese mici cuoom_score_adjridicat (systemd,dbus-daemon,at-spi-bus-laun,sd-pam) din sesiunileuser@1000. - Acumulare de fond: forks
~/.vscode-server(servere VS Code Remote-SSH) rămase orfane după ce conexiunea SSH moare — reparentate la init (PPID=1), vechi de zile — plus sesiunisystemd-logindblocate în stareclosing. Un spike ocazional de Chromium/Playwright împingea totalul peste 16GB → OOM.
Fix 1 — zram swap pe host (pvemini)
Root-ul pvemini e pe ZFS, deci NU se folosește swapfile (risc de deadlock). În loc, zram (swap comprimat în RAM):
# pe pvemini (host)
apt install -y zram-tools
cat > /etc/default/zramswap <<'EOF'
ALGO=zstd
SIZE=8192
PRIORITY=100
EOF
systemctl restart zramswap.service # enabled persistent la boot
zramctl; swapon --show # verificare: /dev/zram0 8G zstd
Acum cei 8GB swap din configul LXC 171 au backing real → vârfurile tranzitorii fac
swap-out în loc de OOM-kill instant.
Același fix aplicat pe pve1 în 2026-07-31 (aceeași cauză: LXC 110 moltbot cu
swap: 4096fictiv → OOM-kill în cgroup + reboot). Config identic,SIZE=8192. Vezi../cluster/incidents/2026-07-31-lxc110-dns-tailscale-oom.md.
Stare swap pe cluster (2026-07-31):
| Nod | Swap | Tip |
|---|---|---|
| pvemini | 8G | zram0 (zstd, prio 100) |
| pve1 | 8G | zram0 (zstd, prio 100) |
| pveelite | 8G | zvol /dev/zd64 (prio -2) — swap real, nu necesită zram |
Fix 2 — reaping orfane (scripts/reap-orphans.sh, cron în 171)
Script conservator care rulează ca root în interiorul containerului, la fiecare 6 ore:
- omoară forks
~/.vscode-serverreparentate la init (PPID=1) și mai vechi de 24h (conexiune SSH moartă); - termină sesiunile
logindîn stareclosingcu leader mort (leader=0).
Exclude explicit daemonul de bază /usr/lib/code-server (lansat de ttyd) și procesele
Claude Code (pot fi task-uri lungi legitime). Log în /var/log/reap-orphans.log.
# instalare în container (din host)
pct push 171 reap-orphans.sh /usr/local/sbin/reap-orphans.sh # sau deploy manual
pct exec 171 -- chmod +x /usr/local/sbin/reap-orphans.sh
# cron: /etc/cron.d/reap-orphans -> 0 */6 * * * root /usr/local/sbin/reap-orphans.sh
# rulare manuală + verificare
pct exec 171 -- /usr/local/sbin/reap-orphans.sh
pct exec 171 -- tail /var/log/reap-orphans.log
⚠️ NU folosi
loginctl terminate-sessionpe sesiuniclosingcare auleader != 0— acelea pot fi sesiuni VS Code remote active de lucru. Doar zombiile culeader=0sunt sigure (asta verifică și scriptul automat).
Diagnostic rapid OOM
# pe host: confirmă că OOM e în cgroup-ul containerului, nu pe host
ssh root@10.0.20.201 "journalctl -k --since '1 hour ago' | grep -iE 'oom_memcg|Killed process'"
cat /sys/fs/cgroup/lxc/171/memory.events # oom / oom_kill counters
cat /sys/fs/cgroup/lxc/171/memory.current # consum curent vs memory.max (16G)
# în container: top consumatori + orfani + sesiuni
pct exec 171 -- bash -c "ps -eo pid,ppid,etimes,rss,comm --sort=-rss | head -20"
pct exec 171 -- loginctl list-sessions
Troubleshooting
Claude Code nu pornește
source ~/.nvm/nvm.sh
which claude
claude --version
tmux nu găsește sesiunea
tmux ls
tmux new -s agent -c /workspace
Git clone eșuează
# Testează conexiunea SSH la Gitea
ssh -T git@gitea.romfast.ro
Tailscale nu funcționează
sudo systemctl status tailscaled
sudo tailscale status
tailscale ip
Instalare Claude Code pe LXC nou (de la zero)
1. Creare LXC în Proxmox
# Pe Proxmox host (ex: pveelite)
pct create <VMID> local:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst \
--hostname claude-agent \
--memory 4096 \
--cores 2 \
--rootfs local-zfs:32 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--features nesting=1 \
--unprivileged 1
pct start <VMID>
pct enter <VMID>
2. Setup sistem (ca root în LXC)
# Update și pachete de bază
apt update && apt upgrade -y
apt install -y curl git tmux sudo
# Creare user claude
useradd -m -s /bin/bash claude
echo "claude ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/claude
passwd claude # setează parola
# Creare /workspace
mkdir -p /workspace
chown claude:claude /workspace
3. Setup user claude
su - claude
# Instalare nvm + Node.js
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20
nvm alias default 20
# Instalare Claude Code
npm install -g @anthropic-ai/claude-code
# Verificare
claude --version
4. Configurare Claude Code
mkdir -p ~/.claude
cat > ~/.claude/settings.json << 'EOF'
{
"permissions": {
"allow": [
"Bash(git *)",
"Bash(npm *)",
"Bash(node *)",
"Read",
"Write",
"Edit"
],
"deny": []
}
}
EOF
5. Configurare tmux
cat > ~/.tmux.conf << 'EOF'
set -g prefix C-a
unbind C-b
bind C-a send-prefix
set -g mouse on
set -g history-limit 50000
set -g default-terminal "screen-256color"
EOF
6. Configurare Git + SSH pentru Gitea
# Generare cheie SSH
ssh-keygen -t ed25519 -f ~/.ssh/gitea_ed25519 -N ""
# Config SSH
cat > ~/.ssh/config << 'EOF'
Host gitea.romfast.ro
HostName gitea.romfast.ro
User git
IdentityFile ~/.ssh/gitea_ed25519
IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config
# Afișează cheia publică (adaug-o în Gitea → Settings → SSH Keys)
cat ~/.ssh/gitea_ed25519.pub
# Config Git
git config --global user.name "Claude Agent"
git config --global user.email "claude@romfast.ro"
git config --global init.defaultBranch main
7. Instalare scripturi workflow
cd /workspace
# Copiază scripturile din acest repo (de pe mașina locală)
# SAU creează-le manual conform secțiunii "Scripturi Disponibile"
# Creare symlink-uri
ln -s /workspace/start-agent.sh ~/start-agent.sh
ln -s /workspace/work.sh ~/work.sh
chmod +x /workspace/*.sh
8. (Opțional) Instalare Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
# Autentifică-te cu contul Tailscale
tailscale ip # notează IP-ul
9. Clonare proiecte
cd /workspace
git clone git@gitea.romfast.ro:romfast/romfastsql.git
# alte proiecte...
10. Test final
~/start-agent.sh
# În tmux:
source ~/.nvm/nvm.sh
claude --version
~/work.sh
Copiere rapidă scripturi (dacă ai alt LXC configurat)
# De pe mașina locală
scp proxmox/lxc171-claude-agent/scripts/*.sh claude@<ip>:/workspace/
ssh claude@<ip> "chmod +x /workspace/*.sh && ln -sf /workspace/start-agent.sh ~/start-agent.sh && ln -sf /workspace/work.sh ~/work.sh"
Legături Utile
- Proxmox Index:
../README.md - Gitea: https://gitea.romfast.ro
Data setup: 2025-12-31 Ultima actualizare: 2026-06-24 (zram swap pvemini + reap-orphans cron, anti-OOM)