Repository navigation
Description
Timing: Follow-up after trial/3 merges into main; defer implementation until then.
Review baseline: Local trial/3 at a094418baf6388e3eeca23821df481a7f0a8751c. This branch is not yet on the remote. Source locations below refer to that snapshot and should be rechecked after merge.
Problem
main_with_args synchronously reads bootstrap configuration from inside its async execution path. File::open and read_to_end can block the executor thread. A byte ceiling limits consumed bytes but does not bound time spent opening or reading a special file.
Evidence and reproduction
tools/cli/src/entry.rs:107: synchronousconfiguration(...)call before awaiting the application builder.tools/cli/src/entry.rs:171-182: direct synchronous file opening and reading.- During review, supplying a FIFO with no writer as
--bootstrapblocked the existing CLI executable until a 2-second watchdog terminated the child. - Unix reproduction: create a FIFO using
mkfifo bootstrap.json, then run the built CLI with--bootstrap bootstrap.json emit profile-search --id abc123under an external watchdog. Do not leave the hung process running.
Acceptance criteria
- Keep blocking file acquisition off async executor threads, or complete it at an explicit synchronous boundary before async execution.
- Define and enforce accepted bootstrap file types; reject unsupported special files without waiting for a writer.
- Preserve byte/encoding/JSON validation, exit policy, and the guarantee that invalid bootstrap data does not invoke the application builder.
- Verify executor progress and special-file handling with bounded watchdog-based checks. Moving work to a blocking worker alone does not make a blocked OS read cancellable.
Code examples and suggested direction
One possible private bridge, after adopting the regular-file policy from #9:
async fn configuration_async(
path: Option<std::path::PathBuf>,
) -> stackpress_lib::Result<stackpress_server::ConfigLayers> {
tokio::task::spawn_blocking(move || configuration(path.as_deref()))
.await
.map_err(stackpress_lib::Error::from_source)?
}Call this helper with .await inside the existing error/exit-code match. It returns the inner configuration result and preserves a blocking-worker join failure as a source.
This moves blocking work off the executor; it does not make a stalled OS operation abortable.
Activity
cblanquera commentedon Oct 26, 2026
Suggested investigation and fix notes
Deferred until
trial/3is merged intomain. Recheck the merged source and tests first. The snippets are examples/proposals, not an approved patch or a change to frozen contracts.main_with→main_with_args→configuration. Preserve one argv parse, invalid-input short circuiting, one builder invocation, and current exit/diagnostic disclosure policy.spawn_blockingdo not fix a FIFO blocked in open.Relevant test invocation:
Coordinate with #9 but keep the responsibilities distinct: this issue owns async scheduling; #9 owns file-acquisition policy. See Tokio's blocking-task cancellation limits.
Implementation workflow: After the merge, follow
.agents/workflows/rust-programming.md: prove the affected behavior, complete the three test-verified review rounds, and record relevant formatting/lints/docs, feature/platform scope, and applicable development coverage. Preserve unrelated changes.cblanquera commentedon Oct 26, 2026
Fixed on
trial/3in 407b4d6 + df443b7 (merged as ff7a251, task 00010 lane 2; not yet onmain, so leaving open).bootstrap blocked executor progress), now passes under a kill/reap watchdog.Coordinator-verified on the combined code: fmt, Clippy -D warnings, Rustdoc -D warnings,
cargo +1.96.0 check, 466 workspace tests and 857 doctests pass (467 tests on mergedtrial/3). Coverage: server 91.61%, CLI 93.15%, transformer 93.62%.Fix owner review issues #10, #3, #8, #9, #13, #12 and host parts of #4,