feat(daemon): extend daemon-by-default to csa review and csa debate#535
Conversation
Generalize the daemon spawn mechanism (introduced in PR #532 for `csa run`) to also apply to `csa review` and `csa debate`. All three execution commands now return a session ID immediately and run in the background by default. `--no-daemon` opts into blocking mode. Key changes: - Add `subcommand` field to `DaemonSpawnConfig` (replaces hardcoded "run") - Extract `check_daemon_flags()` helper in `run_cmd_daemon.rs`, shared by all three commands (run/review/debate) — eliminates inline duplication - Add daemon flags to `ReviewArgs` and `DebateArgs` (daemon, no_daemon, daemon_child, session_id) - Fix #534: rename `daemon_session_id` → `session_id` to match the `--session-id` flag that `spawn_daemon()` passes to the child process - Propagate session exit code from `result.toml` in `session wait` - Convert all workflow patterns to daemon+wait idiom: `SID=$(csa review ...) && csa session wait --session "$SID"` - Add `serial_test` crate for env-var-mutating tests (fixes flaky failures) Design note: `session wait` uses a 250s hardcoded timeout by design — this returns control to the caller periodically so the caller's KV cache stays warm. Callers should retry `session wait` after timeout, not treat it as failure. The daemon child continues running independently of the wait timeout. Closes #534 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
Code Review
This pull request updates the cli-sub-agent to version 0.1.199, generalizing daemon mode support across the run, review, and debate subcommands. It refactors daemon logic into shared utilities, updates workflow patterns to use csa session wait for result retrieval, and introduces the serial_test crate to stabilize tests that mutate environment variables. Feedback identifies a regression in the updated workflow patterns where the transition to csa session wait effectively imposes a 250-second timeout on tasks that previously allowed for much longer durations, potentially causing failures for complex debates or reviews.
| "Provide explicit verdict and confidence in your conclusion." )" | ||
| DEBATE_JSON="$(printf '%s\n' "${DEBATE_PROMPT}" | csa debate --rounds 3 --format json --timeout 1800 --idle-timeout 600 --no-stream-stdout)" || { echo "csa debate failed" >&2; exit 1; } | ||
| SID=$(printf '%s\n' "${DEBATE_PROMPT}" | csa debate --rounds 3 --format json --idle-timeout 600 --no-stream-stdout) || { echo "csa debate failed" >&2; exit 1; } | ||
| DEBATE_JSON="$(csa session wait --session "$SID" 2>&1)" || { echo "csa debate failed" >&2; exit 1; } |
There was a problem hiding this comment.
The csa session wait command has a hardcoded 250s timeout. This change removes the original 1800s timeout from the csa debate command and treats the csa session wait timeout as a hard failure. This contradicts the design note in the PR description: "Callers should retry session wait on timeout, not treat as failure."
This will cause the workflow to fail for any debate that takes longer than 250 seconds. This issue is present in multiple pattern files updated in this PR where long timeouts were previously used.
Please implement a retry loop to handle the timeout from csa session wait correctly. Here is a suggested implementation:
DEBATE_JSON=""
while true; do
# On success, stdout is captured. On timeout (124), stderr is silenced and we loop.
output_part=$(csa session wait --session "$SID" 2>/dev/null)
rc=$?
DEBATE_JSON="${DEBATE_JSON}${output_part}"
if [ $rc -eq 0 ]; then
break
elif [ $rc -ne 124 ]; then
echo "csa debate failed with non-timeout exit code $rc" >&2
exit $rc
fi
echo "csa session wait timed out, retrying..." >&2
done
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5e84b0ce46
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| run_cmd_daemon::check_daemon_flags( | ||
| "debate", | ||
| args.no_daemon, | ||
| args.daemon_child, | ||
| &args.session_id, |
There was a problem hiding this comment.
Preserve stdin prompt support for daemonized debate
Daemonizing debate here changes default behavior for calls that omit question and rely on stdin (for example printf ... | csa debate ...): the parent now exits after spawning, and the child is launched with stdin=/dev/null, so resolve_prompt_with_file reads an empty stream and fails with an empty-stdin prompt error. This is a regression from the previous foreground default and breaks existing piped-debate workflows unless users discover --no-daemon.
Useful? React with 👍 / 👎.
| SID=$(csa review --sa-mode true --range "${DEFAULT_BRANCH}...HEAD") | ||
| csa session wait --session "$SID" 2>&1 | tee "${REVIEW_OUTPUT_FILE}" |
There was a problem hiding this comment.
Retry timed-out session waits in pre-PR review gate
This gate now treats a single csa session wait as definitive, but session wait has a hardcoded 250-second timeout, so long-running cumulative reviews can return exit 124 even while still progressing; the step then fails immediately and blocks merge. The previous command explicitly allowed much longer review runtime (--timeout 1800), so this change introduces false negatives for larger repos unless you loop/retry on timeout before declaring failure.
Useful? React with 👍 / 👎.
Audit Trail: Dismissed bot finding — 250s session wait timeoutFinding: gemini-code-assist flagged that Assessment: This is by design, not a regression. Rationale:
Action: Filed as follow-up work. No code change needed for this PR. |
Summary
csa reviewandcsa debate(all three execution commands now return session ID immediately)check_daemon_flags()helper, eliminating inline daemon logic duplicationdaemon_session_id→session_idto match--session-idCLI flagresult.tomlinsession waitserial_testcrate for flaky env-var test isolationDesign Note
session waituses 250s hardcoded timeout by design — returns control to caller periodically so caller's KV cache stays warm. Callers should retrysession waiton timeout, not treat as failure.Test plan
just pre-commitpasses (2878 unit + 16 E2E tests)weave compile-allpasses (17/17 workflows)main...HEAD(claude-code): PASSCloses #534
🤖 Generated with Claude Code