Problem
Post-merge review of PR #121 reproduced three correctness regressions in async task support:
hide=True leaks stdout/stderr from the async runner.
- Synchronous tasks in an invocation containing an async task receive a coroutine from
ctx.run() and silently skip their command.
- Grouped pre/post task entries can crash async-task detection before execution.
The review also found an under-annotated public ToolkitContext.run surface and documented async-path limitations.
Acceptance criteria
- Async
hide=True suppresses both terminal streams while retaining captured Result output.
- Only coroutine task bodies execute inside
async_task_context; synchronous graph members retain blocking ctx.run() semantics.
- Async-task detection recursively handles grouped pre/post entries; execution does not treat grouping containers as tasks.
ToolkitContext.run exposes the synchronous-or-awaitable Result return contract to type checkers.
- Async documentation removes resolved limitations and retains the current buffered-output, non-interactive/watchers,
sudo, and sync-helper caveats.
- Focused async/grouped-task tests cover each regression.
Reference: docs/async-review-findings.md.
Problem
Post-merge review of PR #121 reproduced three correctness regressions in async task support:
hide=Trueleaks stdout/stderr from the async runner.ctx.run()and silently skip their command.The review also found an under-annotated public
ToolkitContext.runsurface and documented async-path limitations.Acceptance criteria
hide=Truesuppresses both terminal streams while retaining capturedResultoutput.async_task_context; synchronous graph members retain blockingctx.run()semantics.ToolkitContext.runexposes the synchronous-or-awaitableResultreturn contract to type checkers.sudo, and sync-helper caveats.Reference:
docs/async-review-findings.md.