From cac8c3ec81e30d390da492cee7db99a106b59514 Mon Sep 17 00:00:00 2001 From: Mihail Yurasov Date: Sat, 25 Jul 2026 17:11:36 -0700 Subject: [PATCH 1/2] docs(agent-skill): document detached launches for long jobs, instance readiness lifecycle, and the billing model, learned from autonomous-agent field use --- .agents/skills/brev-cli/SKILL.md | 22 +++++++++++++++++++ .agents/skills/brev-cli/prompts/cleanup.md | 3 ++- .../skills/brev-cli/prompts/ml-training.md | 16 +++++++++++--- .agents/skills/brev-cli/reference/commands.md | 5 +++++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/.agents/skills/brev-cli/SKILL.md b/.agents/skills/brev-cli/SKILL.md index cb7b7cc2c..38dff0446 100644 --- a/.agents/skills/brev-cli/SKILL.md +++ b/.agents/skills/brev-cli/SKILL.md @@ -137,6 +137,12 @@ brev create my-instance --startup-script 'pip install torch' brev create my-instance --dry-run ``` +**Instance lifecycle after create:** BUILDING -> RUNNING -> SHELL `READY`. STATUS `RUNNING` +alone is not usable - wait for the SHELL column to show `READY` in `brev ls` before +`exec`/`shell`, and retry the first connection (sshd can refuse for another minute or two +after `READY`). The create readiness poll can end with a spurious-looking `ErrorForbidden` +even though the instance provisions fine - treat it as benign and watch `brev ls` instead. + ### Instance Access ```bash # SSH into instance (interactive shell) @@ -153,6 +159,14 @@ brev exec my-instance @/path/to/script.sh # Run on multiple instances brev exec instance1 instance2 instance3 "nvidia-smi" +# Long-running commands (training runs etc.): brev exec holds the session until the +# command exits - even for `nohup ... &` children - so launch long jobs fully detached +# and poll a completion marker instead of holding the session: +brev exec my-instance @launch.sh # launch.sh ends with: +# setsid nohup python train.py > train.log 2>&1 < /dev/null & disown +# (and the job appends e.g. `echo DONE >> ~/progress.log` when finished) +brev exec my-instance "grep -c DONE ~/progress.log" # cheap poll + # Open in editor brev open my-instance # default editor brev open my-instance code # VS Code @@ -234,6 +248,14 @@ brev invite 3. **Instance Cleanup** ([prompts/cleanup.md](prompts/cleanup.md)) - List instances → Identify unused → Delete +## How Billing Works + +- Billing is **per-second** and only while the instance is RUNNING - BUILDING/provisioning + time is not billed, and there is no round-up to whole hours. +- A **STOPPED instance still accrues storage charges** until it is deleted - stopped is not + free. Delete instances when the work is done. +- Usage/billing data lags real time - numbers checked right after teardown may still grow. + ## Safety Rules - CRITICAL **NEVER do these without explicit user confirmation:** diff --git a/.agents/skills/brev-cli/prompts/cleanup.md b/.agents/skills/brev-cli/prompts/cleanup.md index 1eae1e6c9..b29a77789 100644 --- a/.agents/skills/brev-cli/prompts/cleanup.md +++ b/.agents/skills/brev-cli/prompts/cleanup.md @@ -17,7 +17,8 @@ Parse output to identify: ## Step 2: Identify Candidates for Cleanup Look for: -- Stopped instances (not in use) +- Stopped instances (not in use) - note: **stopped instances still accrue storage charges** + until deleted, so surface them even if they look parked deliberately - Old instances (name suggests temporary use) - Test/dev instances diff --git a/.agents/skills/brev-cli/prompts/ml-training.md b/.agents/skills/brev-cli/prompts/ml-training.md index cbddf3db2..d8c2e697b 100644 --- a/.agents/skills/brev-cli/prompts/ml-training.md +++ b/.agents/skills/brev-cli/prompts/ml-training.md @@ -93,7 +93,14 @@ brev exec "python -c 'import torch; print(torch.cuda.is_available())'" Options: 1. **Interactive:** `brev shell ` then run manually -2. **Background:** `brev exec "nohup python train.py > training.log 2>&1 &"` +2. **Background:** launch fully detached - `brev exec` holds the session until the command + exits, even for `nohup ... &` children, so a plain `nohup ... &` hangs the exec call for + the whole training run. Use a launcher script that detaches and writes a completion marker: + ```bash + # launch.sh (run with: brev exec @launch.sh) + setsid nohup python train.py > training.log 2>&1 < /dev/null & disown + ``` + with the training command appending `echo DONE >> ~/progress.log` when finished. 3. **Editor:** `brev open cursor` ## Step 8: Monitor @@ -102,8 +109,11 @@ Options: # Check GPU usage brev exec "nvidia-smi" -# Check training logs -brev exec "tail -f training.log" +# Check recent training logs (avoid tail -f via exec - it never exits) +brev exec "tail -n 50 training.log" + +# Check for completion +brev exec "grep -c DONE ~/progress.log" ``` ## Cleanup Reminder diff --git a/.agents/skills/brev-cli/reference/commands.md b/.agents/skills/brev-cli/reference/commands.md index 978de983b..c3a416ebc 100644 --- a/.agents/skills/brev-cli/reference/commands.md +++ b/.agents/skills/brev-cli/reference/commands.md @@ -343,6 +343,11 @@ Prefix a file path with `@` to run a local script on the remote instance: - `@setup.sh` - relative path from current directory - `@/absolute/path/script.sh` - absolute path - The script is read locally and executed remotely + +**Long-running commands:** `brev exec` holds the session until the command exits, +including for `nohup ... &` children. For long jobs (training runs), have the script +detach fully (`setsid nohup > run.log 2>&1 < /dev/null & disown`) and write a +completion marker (`echo DONE >> ~/progress.log`) that later `brev exec` calls can poll. - Works with any shell script **Examples:** From 9d21191617be3e107d926f1b92908ee654f791eb Mon Sep 17 00:00:00 2001 From: Mihail Yurasov Date: Sat, 25 Jul 2026 18:48:33 -0700 Subject: [PATCH 2/2] docs(agent-skill): note that stop/start preserves the disk but can change the public IP --- .agents/skills/brev-cli/SKILL.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.agents/skills/brev-cli/SKILL.md b/.agents/skills/brev-cli/SKILL.md index 38dff0446..61c40bc0f 100644 --- a/.agents/skills/brev-cli/SKILL.md +++ b/.agents/skills/brev-cli/SKILL.md @@ -142,6 +142,8 @@ alone is not usable - wait for the SHELL column to show `READY` in `brev ls` bef `exec`/`shell`, and retry the first connection (sshd can refuse for another minute or two after `READY`). The create readiness poll can end with a spurious-looking `ErrorForbidden` even though the instance provisions fine - treat it as benign and watch `brev ls` instead. +Stop/start preserves the disk (venv, payload) but can change the **public IP** - re-run +`brev refresh` and re-resolve any direct endpoints after a restart. ### Instance Access ```bash