Skip to content

feat: operator-initiated clarification escalation — 0.3.7#92

Merged
fakechris merged 2 commits into
mainfrom
feat/clarification-escalation-0.3.7
Apr 23, 2026
Merged

feat: operator-initiated clarification escalation — 0.3.7#92
fakechris merged 2 commits into
mainfrom
feat/clarification-escalation-0.3.7

Conversation

@fakechris

@fakechris fakechris commented Apr 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds the first operator-initiated clarification escalation path, so a low-confidence clarification answer can be routed to the worker as an explicit operator decision instead of just a recommendation.
  • Works from every channel through one canonical do_escalate_clarification action: thin-supervisor clarify ... --escalate CLI, TUI E keybind, and IM /escalate <run_id> [question].
  • Audit-only in 0.3.7 — writes a single clarification_escalated_to_worker timeline event with transport="pending_0_3_8". Actual side-instruction transport to the worker (queue drain by SupervisorLoop + worker-reply capture) lands in 0.3.8.

What's included

  • supervisor/app.pythin-supervisor clarify <run_id> <question> [--escalate] [--operator <name>]
  • supervisor/daemon/server.py_do_escalate_clarification dispatch + handler (resolves both active and on-disk runs)
  • supervisor/daemon/client.pyescalate_clarification(...) IPC method
  • supervisor/operator/actions.pydo_escalate_clarification(ctx, ...) piggy-backing on the explain capability; daemon path on ASYNC_DAEMON, direct session-log write on ASYNC_LOCAL
  • supervisor/operator/tui.py — tracks the last clarification answer; on escalation_recommended=True shows the hint and binds E to escalate
  • supervisor/operator/command_dispatch.py/escalate <run_id> [question]; with no override pulls question + confidence from the most recent clarification_response event
  • Tests: 4 action tests, 4 daemon IPC tests (incl. client roundtrip), 4 dispatch tests, 2 formatter tests
  • pyproject.toml bumped to 0.3.7; CHANGELOG + README updated

Test plan

  • pytest -q — 1229 passed
  • python -m supervisor.app clarify --help renders the new CLI parser
  • Smoke: thin-supervisor clarify <run_id> "why paused?" --escalate against a completed local run writes the expected event to .supervisor/runtime/runs/<run_id>/session_log.jsonl
  • Smoke: TUI c → low-confidence answer surfaces the E hint → E records the event

Open in Devin Review

Summary by CodeRabbit

New Features

  • Operator-initiated clarification escalation
    • Added clarify CLI command with optional escalation flag
    • Added TUI keybind (E) for escalating low-confidence responses
    • Added IM /escalate command for operator workflows
    • Escalation decisions recorded in run timeline for audit compliance

Operators can now escalate a low-confidence clarification to the worker
from any channel. Escalation is an auditable decision today; the actual
side-instruction transport to the worker ships in 0.3.8.

- CLI: thin-supervisor clarify <run_id> <question> [--escalate]
- Daemon: escalate_clarification IPC + DaemonClient.escalate_clarification
- Actions: do_escalate_clarification (daemon + local fallback)
- TUI: 'E' keybind + escalate hint in format_clarification
- IM: /escalate <run_id> [question] — defaults to last clarification_response
- Emits a single clarification_escalated_to_worker event with
  transport="pending_0_3_8" so the audit trail is unambiguous.
@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@fakechris has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 43 minutes and 46 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 43 minutes and 46 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 829c280e-5ac0-4dac-bca0-b076d1f33466

📥 Commits

Reviewing files that changed from the base of the PR and between e1178ec and 7088ad3.

📒 Files selected for processing (5)
  • supervisor/app.py
  • supervisor/operator/actions.py
  • supervisor/operator/tui.py
  • tests/test_command_dispatch.py
  • tests/test_operator_actions.py
📝 Walkthrough

Walkthrough

This PR introduces operator-initiated clarification escalation functionality in version 0.3.7. It adds a CLI clarify command with --escalate flag, daemon IPC escalate_clarification handler, operator action do_escalate_clarification, IM /escalate command, TUI E keybind, and records clarification_escalated_to_worker timeline events for audit purposes.

Changes

Cohort / File(s) Summary
Version & Documentation
CHANGELOG.md, README.md, pyproject.toml
Bump version from 0.3.6 to 0.3.7 and document new operator-initiated clarification escalation feature across CLI, TUI, and IM surfaces.
CLI Entry Point
supervisor/app.py
Add cmd_clarify subcommand to submit clarification jobs with async polling, handle --escalate flag to trigger escalation via do_escalate_clarification, and parse arguments including question, language, operator, and timeout.
Daemon IPC Layer
supervisor/daemon/client.py, supervisor/daemon/server.py
Introduce escalate_clarification client method and server handler to persist operator escalation decisions as clarification_escalated_to_worker events with deterministic escalation_id generation, supporting both active (StateStore) and completed runs (on-disk timeline).
Operator Actions & Command Dispatch
supervisor/operator/actions.py, supervisor/operator/command_dispatch.py
Add do_escalate_clarification public action gating on explain capability and routing through daemon (labeled "daemon" source) or local session log (labeled "local" source with transport: "pending_0_3_8"); add /escalate IM command that derives question and confidence from latest stored clarification_response or accepts user-supplied question.
TUI Enhancement
supervisor/operator/tui.py
Display "press 'E' to escalate" warning for low-confidence clarifications (escalation_recommended=True), wire E keybind to invoke do_escalate_clarification with reason="tui_low_confidence", and store clarification context for reuse.
Test Coverage
tests/test_command_dispatch.py, tests/test_daemon.py, tests/test_operator_actions.py, tests/test_tui.py
Add comprehensive test suites validating IM command argument handling, daemon event persistence with proper payloads, local vs. daemon action branching, and TUI conditional UI rendering based on escalation recommendation.

Sequence Diagram

sequenceDiagram
    participant User as User (TUI)
    participant TUI as TUI UI Layer
    participant OpAction as Operator Action
    participant Daemon as Daemon Server
    participant SessionLog as Session Log

    User->>TUI: Press 'E' key (low-confidence clarification)
    TUI->>OpAction: do_escalate_clarification(question, confidence, reason="tui_low_confidence")
    
    alt Daemon Available
        OpAction->>Daemon: escalate_clarification(run_id, question, reason, operator, confidence)
        Daemon->>SessionLog: append clarification_escalated_to_worker event
        Daemon-->>OpAction: {ok: true, escalation_id}
        OpAction-->>TUI: {source: "daemon", escalation_id}
    else Local Mode
        OpAction->>SessionLog: append clarification_escalated_to_worker event (transport: "pending_0_3_8")
        OpAction-->>TUI: {source: "local", escalation_id}
    end
    
    TUI->>User: Display escalation_id in status bar
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

Escalate with ease through E and slash commands fair, 🐰
From TUI, daemon, and instant-message air,
Low-confidence answers now bubble right up,
In timeline events—a worker's full cup! ✨
Version point-three-seven brings clarity to bear.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: operator-initiated clarification escalation, with version 0.3.7 denoting the release scope.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/clarification-escalation-0.3.7

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the version to 0.3.7 and introduces operator-initiated clarification escalation across CLI, TUI, and IM interfaces. Key additions include a new clarify command, daemon IPC support for escalation, and audit logging for these actions. Feedback highlights a logic error in the IM command dispatcher where the oldest rather than the newest clarification is selected for escalation, and a state management issue in the TUI where escalation hints persist across different runs.

from supervisor.operator.api import timeline_from_session_log

events = timeline_from_session_log(log_path, limit=50)
for ev in events:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The loop iterates through events in chronological order (assuming timeline_from_session_log returns them as they appear in the log). This means it will find the oldest clarification response within the window, rather than the most recent one. This can lead to escalating an outdated question if multiple clarifications have occurred.

Suggested change
for ev in events:
for ev in reversed(events):

Comment thread supervisor/operator/tui.py Outdated
"escalation_recommended": True,
"language": pending_job.get("language", language),
}
status_msg = " Low-confidence answer — press 'E' to escalate, any other key to dismiss "

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The last_clarify state and the associated status_msg are not cleared when the user navigates between runs (e.g., using 'j' or 'k'). This results in a stale "press 'E' to escalate" hint remaining visible while a different run is selected. If the user then presses 'E', it will escalate the clarification for the previous run while the UI highlights the current one, which is misleading and potentially error-prone.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

coderabbitai[bot]

This comment was marked as resolved.

- actions.do_escalate_clarification: strip+reject empty/whitespace
  questions at the top so the daemon path and local path behave
  consistently (CodeRabbit).
- app.cmd_clarify: catch ConnectionRefusedError/FileNotFoundError/OSError
  around submit_clarification, each poll_job iteration, and
  do_escalate_clarification, matching the cmd_observe pattern so a
  daemon that dies mid-clarify surfaces a clean error instead of a
  traceback (CodeRabbit).
- tui: drop the unimplemented "any other key to dismiss" promise from
  the escalation status; clear last_clarify when the operator navigates
  to a different run via j/k so a subsequent 'E' can't escalate a
  clarification for a run the operator is no longer looking at
  (gemini/CodeRabbit).
- tests: add a regression test that proves /escalate resolves the
  newest clarification_response when multiple exist (gemini flagged
  ordering; verified newest-first is correct, now pinned by a test);
  add a unit test for the new empty-question guard.
@fakechris
fakechris merged commit 4d7b62a into main Apr 23, 2026
5 of 6 checks passed
@fakechris
fakechris deleted the feat/clarification-escalation-0.3.7 branch April 23, 2026 02:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant