Skip to content

fix(daemon): ride out projectless mounting refusals in the CLI - #2632

Merged
ScriptedAlchemy merged 1 commit into
masterfrom
fleet/redaction-json-master-reds-2
Sep 29, 2026
Merged

ScriptedAlchemy merged 1 commit into
masterfrom
fleet/redaction-json-master-reds-2

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Fixes #2559

Cause (production bug, not a stale pin)

core_cli_suite::cli_non_interactive_test::sessions_search_omits_absent_optional_filters_and_preserves_provider spawns a daemon and immediately runs tracedecay sessions search. If that call lands during the cold open, it hits the daemon's projectless tools/call route. The owner answers the retryable application.runtime.mounting refusal. The route then calls structure_tool_problem (#2345), which moves the record into MCP structuredContent.problem, the shape tracedecay serve relays to hosts. The one-shot client's ride-out check, tool_result_retry_after_delay, only read a top-level problem. It found nothing and returned the mounting refusal as the answer. The CLI's retained decoder does parse the refusal from the JSON text payload, hence refused: application.runtime.mounting after about 0.5 s instead of a retry.

Literal reply captured with a temporary client-side print (not committed) during a failing run:

DIAG result={"_meta":{...},"content":[{"text":"{...\"problem\":{...\"code\":\"application.runtime.mounting\"...}"}],"isError":true,
  "structuredContent":{"problem":{"code":"application.runtime.mounting","retry":"after_delay","retry_after_millis":250,"terminality":"pre_admission",...}}}

The reply has no top-level problem. Whether a run fails depends on load (whether the first call beats the open), so the test failed consistently on the shared host and sometimes passed on a quiet one.

Change

tool_result_retry_after_delay reads the problem record from problem, or else from structuredContent.problem. Those are the two shapes the daemon socket emits today (project route, projectless route). Nothing else changes: only a pre-admission after_delay mounting record is re-sent.

Fail before / pass after

New unit test daemon::core_client::tests::projectless_mounting_refusal_is_re_sent_after_its_delay. It builds the refusal with the production record authority, applies the production structure_tool_problem, and asserts:

  • no top-level problem
  • project_open_retry_wait returns Some(250ms)
  • a non-mounting authority-unavailable problem in the same shape returns None

With the fix reverted:

assertion `left == right` failed
  left: None
 right: Some(250ms)
test result: FAILED. 0 passed; 1 failed

With the fix: daemon::core_client:: 6 passed.

Runtime proof (built CLI, real daemon)

The failing journey is the CLI test itself: the built tracedecay binary against a real spawned daemon. Six copies ran in parallel to recreate host load:

  • master at 75926a1: FAILED in 5 of 6 sequential runs, and 1 of 6 (with 6/6 in an earlier load window) in parallel, always with Error: config error: daemon tool tracedecay_message_search refused: application.runtime.mounting
  • this branch: 6/6 ok in three parallel rounds (18/18), and 6/6 again after rebasing on e786590

Checks

  • core_cli_suite (--features tracedecay/test-helpers,tracedecay/search-eval, the CI root-journeys selection): 169 passed, 0 failed
  • cargo clippy -p tracedecay --all-targets --features test-helpers,test-transport -- -D warnings: clean
  • cargo fmt --all -- --check: clean

The one-shot client re-sends a tool call while the owner answers
application.runtime.mounting, but it only looked for the problem record
at the tool result's top level. The daemon's projectless tools/call
route moves that record into MCP structuredContent (the shape
tracedecay serve relays to hosts), so a CLI call that landed on that
route during a cold open returned the mounting refusal as its answer.
The retry check now reads the record from either location.

Fixes #2559
@ScriptedAlchemy
ScriptedAlchemy merged commit 474d5c9 into master Sep 29, 2026
6 of 7 checks passed
@changeset-bot

changeset-bot Bot commented Sep 29, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9935023

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-29T11:56:50.286233Z 9935023 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ScriptedAlchemy
ScriptedAlchemy deleted the fleet/redaction-json-master-reds-2 branch September 29, 2026 13:39
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.

test(cli): sessions_search_omits_absent_optional_filters fails on master with runtime mounting

1 participant