When a scheduled task targets a session still open in the terminal, the task runs and changes files but the TUI stays on the previous response. The user cannot see its progress or completion.
Observed with Homebrew jcode 0.84.0 on macOS arm64 (jcode version reports v0.84.0-dev (unknown)). The same relevant code is present in master at 4e85d44.
Reproduction
- Keep a jcode TUI session open and idle.
- Schedule a task targeting that existing session.
- Wait until it becomes due.
- Compare the TUI with the session journal and files changed by the task.
Expected: the existing TUI receives the scheduled turn's text, tool activity and terminal completion event.
Actual: the scheduled work executes through headless resume; the TUI retains the previous response. The daemon log at the due time contains (session ID redacted):
Ambient runner: live delivery for <session> fell back to headless resume: Client must Subscribe with a working_dir before sending stateful requests
Cause and deterministic reproduction
AmbientRunnerHandle::notify_live_session opens a fresh Client and sends NotifySession without subscribing. Request::is_lightweight_control_request() excludes that request, so the server's initial-request gate rejects it before handle_notify_session can run. The scheduler catches this error and calls resume_dead_session_with_reminder, which uses a separate Agent and capture-mode output even though the original TUI is still connected.
A regression test using a real server on an isolated local socket and a fake streaming provider reproduces the problem without credentials or a real model: calling deliver_scheduled_direct_item completes, but the original subscribed client times out waiting for text and Done { id: 0 }.
I have a small proposed fix routing this explicitly session-targeted notification through the existing lightweight control handler, reusing handle_notify_session. The same regression then receives both output and completion; an unknown target still returns an error.
Proposed patch and validation
PR creation was rejected because this repository currently has pull_request_creation_policy: collaborators_only. The proposed fix is available for maintainer review:
The patch changes three files: request classification, routing to the existing notification handler, and a regression test. Validation on that base:
cargo test -p jcode-app-core --no-default-features ambient::runner::runner_tests: 5 passed
cargo test -p jcode-app-core --no-default-features notify_session_: 2 passed
cargo test -p jcode-protocol: 79 passed
- Changed-file rustfmt check and
git diff --check: passed
- The new regression fails before the fix and passes afterward.
Repository-wide test-size, code-size, panic and swallowed-error ratchets already fail on the unmodified base; all four produce identical failures with this patch. No baseline files were changed. Full all-feature/workspace CI was not run locally.
When a scheduled task targets a session still open in the terminal, the task runs and changes files but the TUI stays on the previous response. The user cannot see its progress or completion.
Observed with Homebrew jcode 0.84.0 on macOS arm64 (
jcode versionreportsv0.84.0-dev (unknown)). The same relevant code is present in master at 4e85d44.Reproduction
Expected: the existing TUI receives the scheduled turn's text, tool activity and terminal completion event.
Actual: the scheduled work executes through headless resume; the TUI retains the previous response. The daemon log at the due time contains (session ID redacted):
Cause and deterministic reproduction
AmbientRunnerHandle::notify_live_sessionopens a freshClientand sendsNotifySessionwithout subscribing.Request::is_lightweight_control_request()excludes that request, so the server's initial-request gate rejects it beforehandle_notify_sessioncan run. The scheduler catches this error and callsresume_dead_session_with_reminder, which uses a separateAgentand capture-mode output even though the original TUI is still connected.A regression test using a real server on an isolated local socket and a fake streaming provider reproduces the problem without credentials or a real model: calling
deliver_scheduled_direct_itemcompletes, but the original subscribed client times out waiting for text andDone { id: 0 }.I have a small proposed fix routing this explicitly session-targeted notification through the existing lightweight control handler, reusing
handle_notify_session. The same regression then receives both output and completion; an unknown target still returns an error.Proposed patch and validation
PR creation was rejected because this repository currently has
pull_request_creation_policy: collaborators_only. The proposed fix is available for maintainer review:4e85d4423cfd248236044564aa8e4d48ce0ae473The patch changes three files: request classification, routing to the existing notification handler, and a regression test. Validation on that base:
cargo test -p jcode-app-core --no-default-features ambient::runner::runner_tests: 5 passedcargo test -p jcode-app-core --no-default-features notify_session_: 2 passedcargo test -p jcode-protocol: 79 passedgit diff --check: passedRepository-wide test-size, code-size, panic and swallowed-error ratchets already fail on the unmodified base; all four produce identical failures with this patch. No baseline files were changed. Full all-feature/workspace CI was not run locally.