-
Notifications
You must be signed in to change notification settings - Fork 0
fix(noema): surface real sidecar fail-closed diagnostics past redaction #1425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5bae5a3
b124b31
b169623
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -271,6 +271,22 @@ log "starting review sidecar on ${ORCHESTRATOR_HOST}:${ORCHESTRATOR_PORT}" | |
| cp "$ORCHESTRATOR_LAUNCHER" "$ORCHESTRATOR_WORK/launch_sidecar.py" | ||
| export ORCHESTRATOR_CATALOG_LIMIT="$CATALOG_LIMIT" | ||
| export ORCHESTRATOR_CATALOG_FAMILY_CAP="$CATALOG_FAMILY_CAP" | ||
| # Stream stdout/stderr through the redacting sanitizer as two named, awaitable | ||
| # processes (not bare `> >(...)` substitutions, whose PIDs bash never exposes) | ||
| # so a failure handler can wait for the sanitizer to finish flushing before it | ||
| # reads the sanitized file — otherwise the read can race the still-draining | ||
| # pipe and silently show an empty/truncated diagnostic (the exact class of bug | ||
| # this sanitizer exists to avoid: see the 2026-08-30 sidecar-diagnostics gap | ||
| # baseline entry). | ||
| exec {orchestrator_stdout_fd}> >("$sidecar_python" -u "$SIDECAR_LOG_SANITIZER" > "$sidecar_stdout") | ||
| stdout_sanitizer_pid=$! | ||
| exec {orchestrator_stderr_fd}> >("$sidecar_python" -u "$SIDECAR_LOG_SANITIZER" > "$sidecar_stderr") | ||
| stderr_sanitizer_pid=$! | ||
| wait_for_sidecar_sanitizers() { | ||
| wait "$stdout_sanitizer_pid" 2>/dev/null || true | ||
| wait "$stderr_sanitizer_pid" 2>/dev/null || true | ||
| } | ||
|
|
||
| PYTHONPATH="$ORCHESTRATOR_SOURCE:$ORG_REPO_ROOT" \ | ||
| CONTEXTUAL_ORCHESTRATOR_TOKEN="$ORCHESTRATOR_TOKEN" \ | ||
| "$sidecar_python" "$ORCHESTRATOR_WORK/launch_sidecar.py" \ | ||
|
|
@@ -283,16 +299,22 @@ PYTHONPATH="$ORCHESTRATOR_SOURCE:$ORG_REPO_ROOT" \ | |
| "${zdr_args[@]}" \ | ||
| "${privacy_args[@]}" \ | ||
| "${pool_args[@]}" \ | ||
| > >("$sidecar_python" -u "$SIDECAR_LOG_SANITIZER" > "$sidecar_stdout") \ | ||
| 2> >("$sidecar_python" -u "$SIDECAR_LOG_SANITIZER" > "$sidecar_stderr") & | ||
| >&"$orchestrator_stdout_fd" 2>&"$orchestrator_stderr_fd" & | ||
| sidecar_pid=$! | ||
| # Close our own copies of the write ends now that the sidecar process holds | ||
| # its own duplicated fds. If these stayed open in this shell, the sanitizer | ||
| # process substitutions would never see EOF (and never exit) once the sidecar | ||
| # itself closes its fds, since a process substitution's reader only finishes | ||
| # after every writer has closed. | ||
| exec {orchestrator_stdout_fd}>&- {orchestrator_stderr_fd}>&- | ||
| cleanup_sidecar_on_error() { | ||
| status=$? | ||
| if [ "$status" -ne 0 ]; then | ||
| publish_sidecar_evidence || true | ||
| log "stopping failed sidecar (pid $sidecar_pid)" | ||
| kill "$sidecar_pid" 2>/dev/null || true | ||
| wait "$sidecar_pid" 2>/dev/null || true | ||
| wait_for_sidecar_sanitizers | ||
| fi | ||
| } | ||
| trap cleanup_sidecar_on_error EXIT | ||
|
|
@@ -302,6 +324,11 @@ until curl -fsSL --max-time 2 "http://${ORCHESTRATOR_HOST}:${ORCHESTRATOR_PORT}/ | |
| if ! kill -0 "$sidecar_pid" 2>/dev/null; then | ||
| sidecar_status=0 | ||
| wait "$sidecar_pid" || sidecar_status=$? | ||
| # The sidecar has fully exited (confirmed above), so its stderr pipe has | ||
| # already sent EOF; draining the sanitizer here cannot hang, and it | ||
| # guarantees $sidecar_stderr holds everything the sidecar wrote before we | ||
| # read it for the failure message below. | ||
| wait_for_sidecar_sanitizers | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Startup timeout still races diagnostics When startup times out, Prompt for agentsWas this helpful? React with 👍 or 👎 to provide feedback. |
||
| fail "sidecar exited before healthz (status ${sidecar_status}); stderr: $(sed -n '1,20p' "$sidecar_stderr")" | ||
| fi | ||
| i=$((i + 1)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,8 +15,21 @@ | |
| ("review sidecar preflight failed:", "review sidecar preflight failed"), | ||
| ("review sidecar discovery failed:", "review sidecar discovery failed"), | ||
| ( | ||
| "review sidecar discovered no zero-cost models;", | ||
| "review sidecar discovered no zero-cost models", | ||
| # Matches contextual_orchestrator_review_launcher.py's actual | ||
| # SystemExit text ("no eligible models", not "no zero-cost models" -- | ||
| # that stale prefix never matched the launcher's real message, so | ||
| # this fail-closed diagnostic was silently dropped to | ||
| # omitted_unstructured_lines instead of reaching CI operators). | ||
| "review sidecar discovered no eligible models;", | ||
| "review sidecar discovered no eligible models", | ||
|
seonghobae marked this conversation as resolved.
|
||
| ), | ||
| ( | ||
| "review sidecar requires an explicit --auth-token or the KV credential", | ||
| "review sidecar auth token unavailable", | ||
| ), | ||
| ( | ||
| "review sidecar requires at least one provider credential in the KV", | ||
| "review sidecar requires at least one provider credential in the KV", | ||
| ), | ||
|
Comment on lines
17
to
33
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| ) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 Info: Named sanitizer processes drain correctly
Each immediate
$!captures its sanitizer. Closing the parent write descriptors permits EOF, so the early-exit drain completes before stderr is read.(Refers to this code)
Was this helpful? React with 👍 or 👎 to provide feedback.