원클릭으로
nohup-poll
Launch long-running commands (>4 min) via nohup and poll at kv_cache.long_poll_seconds (default 240s) to keep KV cache warm.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Launch long-running commands (>4 min) via nohup and poll at kv_cache.long_poll_seconds (default 240s) to keep KV cache warm.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | nohup-poll |
| description | Launch long-running commands (>4 min) via nohup and poll at kv_cache.long_poll_seconds (default 240s) to keep KV cache warm. |
| allowed-tools | Bash, Read, Glob |
Launch long-running commands as true background processes and poll at the
configured long-poll interval from kv_cache.long_poll_seconds (default 240s).
Each poll is a separate Bash tool call that triggers a new API request,
keeping the provider's KV cache warm.
Use this skill when the caller needs periodic API activity to keep its KV cache warm.
Default CSA guidance assumes a 5-minute cache (long_poll_seconds = 240), while
Max-tier Opus users can raise kv_cache.long_poll_seconds to 3000 for a 1-hour cache.
| Event | Cost |
|---|---|
| Cache HIT (prefix reused within TTL) | 1/12.5 of miss price |
| Cache MISS (TTL expired or first call) | Full price |
A 10-minute blocking Bash call creates a >5 min gap between API calls. The entire context (100K+ tokens) is re-read at full miss price.
One cold restart on a 100K context ≈ 2500 cache-hit polling rounds.
For a typical 15-minute cargo build:
MUST use for any command expected to exceed 4 minutes:
| Command | Typical Duration | Polls (default ~240s each) |
|---|---|---|
cargo build (full, large project) | 5–15 min | 1–4 |
just pre-commit (with e2e tests) | 5–20 min | 1–5 |
cargo install --locked <large> | 10–30 min | 2–7 |
csa run / csa review / csa debate | 5–60 min | 1–15 |
| Data processing / rsync | varies | varies |
Do NOT use for commands under 4 minutes — the overhead isn't worth it.
Do NOT use for csa session wait — call csa session wait directly because it
already applies the internal long-poll cap.
Look for scripts/bg.sh in the project root. If missing, create it:
mkdir -p scripts && cat > scripts/bg.sh << 'BGEOF'
#!/bin/bash
set -euo pipefail
if [ $# -lt 2 ]; then echo "Usage: bg.sh <logfile> <command...>" >&2; exit 1; fi
LOGFILE="$1"; shift
LOGDIR="$(dirname "$LOGFILE")"
mkdir -p "$LOGDIR"
LOGFILE="$(cd "$LOGDIR" && pwd)/$(basename "$LOGFILE")"
export LOGFILE
nohup bash -c '"$@"; echo $? > "${LOGFILE}.exitcode"' _ "$@" >> "$LOGFILE" 2>&1 &
PID=$!; echo "PID=$PID LOG=$LOGFILE"
sleep 3
if kill -0 "$PID" 2>/dev/null; then echo "ALIVE pid=$PID"; exit 0
else
if [ -f "${LOGFILE}.exitcode" ] && [ "$(cat "${LOGFILE}.exitcode")" = "0" ]; then
echo "DONE pid=$PID exit=0"; exit 0
fi
echo "DEAD pid=$PID exit=$(cat "${LOGFILE}.exitcode" 2>/dev/null || echo unknown)" >&2
tail -20 "$LOGFILE" >&2; exit 1
fi
BGEOF
chmod +x scripts/bg.sh
bash scripts/bg.sh "/tmp/<task>-$(date +%s).log" <command...>
Parse the output to extract PID and LOG path. If output says DEAD, the
command failed immediately — read the log and stop.
CRITICAL: Each poll MUST be a separate Bash tool call. A while sleep
loop inside one Bash call defeats the purpose — the entire loop is one API
gap and the cache expires.
Single poll command (copy-paste ready):
sleep "$(csa config get kv_cache.long_poll_seconds --default 240)" && if kill -0 <PID> 2>/dev/null; then echo "POLL:RUNNING"; tail -3 "<LOG>"; else echo "POLL:DONE exit=$(cat "<LOG>.exitcode" 2>/dev/null || echo unknown)"; tail -20 "<LOG>"; fi
Set Bash timeout high enough to cover the configured sleep plus margin. With the default 240s poll, 300000 ms is sufficient.
After each poll, decide:
| Output contains | Action |
|---|---|
POLL:RUNNING | Issue another identical poll (new Bash call) |
POLL:DONE exit=0 | Success — proceed with workflow |
POLL:DONE exit=<N> | Failure — read full log, diagnose |
When process finishes, read the full log:
cat "<LOG>"
Or tail a reasonable amount if the log is large:
tail -100 "<LOG>"
If you have independent work to do while waiting (read-only research, documentation, etc.), you can interleave:
kill -0 <PID> 2>/dev/null && echo "STILL_RUNNING" || echo "DONE"
The rule: never let more than kv_cache.long_poll_seconds pass without an API interaction
(any tool call counts — Read, Grep, Bash, etc.).
| Context | Typical TTL | Suggested kv_cache.long_poll_seconds |
|---|---|---|
| Legacy / Haiku / generic 5-min cache | 300s | 240 |
| Max-tier Opus 1-hour cache | 3600s | 3000 |
Keep a safety margin instead of polling exactly at the provider TTL.
Each poll adds ~200–500 tokens of history. After N polls:
| Polls | Duration | Accumulated Tokens | Cost vs Cold Restart (100K ctx) |
|---|---|---|---|
| 5 | ~20 min | ~2.5K | 0.2% |
| 20 | ~80 min | ~10K | 0.8% |
| 100 | ~7 hours | ~50K | 4% |
| 350 | ~1 day | ~175K | 14% |
Even polling continuously for a full day costs only ~14% of one cold restart. The break-even point is ~12–18 days of continuous polling.
# Step 1: Launch
bash scripts/bg.sh "/tmp/cargo-build-$(date +%s).log" cargo build --release
# → PID=12345 LOG=/tmp/cargo-build-1743666000.log
# Step 2: First poll (separate Bash call; with default 240s, timeout 300000ms is fine)
sleep "$(csa config get kv_cache.long_poll_seconds --default 240)" && if kill -0 12345 2>/dev/null; then echo "POLL:RUNNING"; tail -3 "/tmp/cargo-build-1743666000.log"; else echo "POLL:DONE exit=$(cat "/tmp/cargo-build-1743666000.log.exitcode" 2>/dev/null || echo unknown)"; tail -20 "/tmp/cargo-build-1743666000.log"; fi
# Step 3: Repeat until POLL:DONE
# Step 1: Launch
bash scripts/bg.sh "/tmp/csa-run-$(date +%s).log" csa run --sa-mode true --tier tier-1 "Implement feature X"
# → PID=23456 LOG=/tmp/csa-run-1743666000.log
# Step 2: Poll
sleep "$(csa config get kv_cache.long_poll_seconds --default 240)" && if kill -0 23456 2>/dev/null; then echo "POLL:RUNNING"; tail -3 "/tmp/csa-run-1743666000.log"; else echo "POLL:DONE exit=$(cat "/tmp/csa-run-1743666000.log.exitcode" 2>/dev/null || echo unknown)"; tail -20 "/tmp/csa-run-1743666000.log"; fi
# Step 1: Launch
bash scripts/bg.sh "/tmp/precommit-$(date +%s).log" just pre-commit
# → PID=34567 LOG=/tmp/precommit-1743666000.log
# Step 2: Poll
sleep "$(csa config get kv_cache.long_poll_seconds --default 240)" && if kill -0 34567 2>/dev/null; then echo "POLL:RUNNING"; tail -3 "/tmp/precommit-1743666000.log"; else echo "POLL:DONE exit=$(cat "/tmp/precommit-1743666000.log.exitcode" 2>/dev/null || echo unknown)"; tail -20 "/tmp/precommit-1743666000.log"; fi
| Wrong | Why | Correct |
|---|---|---|
while sleep 240; do check; done in one Bash call | Single API gap — cache expires | Separate Bash call per poll |
sleep 400 && check when kv_cache.long_poll_seconds = 240 | Sleep exceeds the configured safe band | sleep "$(csa config get kv_cache.long_poll_seconds --default 240)" |
run_in_background: true then forget | No periodic API calls — cache expires | Poll or do other work |
| Blocking Bash with 600s timeout | 600s > TTL — cache expires | Use nohup-poll instead |
wait <PID> from a later Bash call | PID is not a child of the new shell, so wait returns 127 | Read <LOG>.exitcode written by bg.sh |
Use when: full dev cycle branch->plan->implement->review->PR->merge
Use when: executing tasks via csa run/review/debate, session mgmt
Use when: iterative review-fix loop until csa review --diff is clean
Use when: running CSA-driven code review, independent model selection
Use when: three-layer manager-employee orchestration for delegation
Use when: legacy alias, redirects to dev2merge pipeline