Known limitation: interactive hooks can conflict during parallel service execution
- Dominant language
- Go
- Stars
- 569
- Forks
- 364
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 136
Description
## Summary
With the introduction of the graph-driven execution engine in #7776, service-level steps (package, deploy) now run concurrently across services. However, there is no guard to prevent multiple `interactive: true` hooks from competing for the console simultaneously.
## Problem
When a hook is configured with `interactive: true`, it binds stdin/stdout/stderr directly to the console. If two services both define interactive hooks at the same phase (e.g., `predeploy`), the exegraph scheduler will run them concurrently, causing:
- Garbled terminal output
- User input routed to the wrong prompt
- Data races on console state
The `syncConsole` wrapper in `provision_graph.go` intentionally does **not** wrap interactive methods (`Prompt`, `Select`, `Confirm`), and the scheduler has no concept of "interactive" nodes.
### Extensions make this harder
Extensions also support lifecycle hooks, and azd has no way to know ahead of time whether an extension hook will prompt the user. This means even if we validate `interactive: true` on user-defined hooks, extension-driven hooks could still compete for the console without warning.
## Scope
- **Project-level hooks** (`preprovision`, `predeploy`, `prepackage`, etc.) are safe — they are single nodes in the DAG with serializing dependency edges.
- **Service-level hooks** (per-service `prepackage`, `predeploy`, etc.) are the risk — they run in parallel across services.
This is likely an edge case in practice, since having multiple interactive service hooks is uncommon.
## Possible mitigations
1. **Disable parallel execution** when any service hook has `interactive: true` — simplest but loses parallelism.
2. **Require lifecycle events from hooks** to declare whether they are interactive — hooks/extensions could signal that they need exclusive console access.
3. **Console ownership protocol** — a mechanism for a hook to acquire exclusive console access (serialize only when needed, preserving parallelism for non-interactive work).
4. **Validate and warn** — emit a warning at graph construction time if multiple services have `interactive: true` hooks at the same phase.
## Related
- PR #7776 — graph-driven execution engine for up/provision/deploy
Contributor guide
Assessment
This issue has not been assessed yet.