iOfficeAI / iOfficeAI/AionCore
[Enhancement] `aioncore team <subcommand>` with empty stdin blocks forever in read(stdin) - fail fast with e.g. TEAM_CLI_STDIN_MISSING
- Dominant language
- Rust
- Stars
- 105
- Forks
- 169
- Avg merge
- 5h 58m
- Merged PRs (30d)
- 84
Description
### Module
`aioncore team` CLI (JSON-over-stdin transport)
### Platform
Windows 11 (desktop app); presumably all platforms since this is stdin handling
### AionCore Version
aioncore 0.1.72 (AionUi desktop build)
---
### Problem
`aioncore team ` invoked **without** feeding JSON on stdin blocks indefinitely in `read(stdin)` and prints nothing. Measured: blocked ~2 minutes until an external timeout killed it, with no diagnostic output at any point.
The failure is silent in exactly the worst way for our use case. These commands are called by **agents**, not humans. When the call hangs with no output, the calling agent cannot distinguish:
- "stdin is missing, I made a usage error" (instantly fixable), from
- "the platform is slow / the teammate died / the channel is broken" (escalate).
Agents therefore conclude "teammate unreachable / team broken" and escalate a usage error as an incident.
### Reproduction
```bash
# blocks, prints nothing, until killed externally
aioncore team members
```
Independently reproduced by two different team leads on separate machines with `aioncore team members` (no stdin). Every `team` subcommand appears to behave this way; the JSON is mandatory, so the correct call is:
```bash
echo '{}' | aioncore team members
```
### New victim samples (2026-08-31, today)
1. **A teammate lost ~22 minutes on its very first assignment.** It tried the `team` commands without piping JSON, hit the silent block, and repeatedly retried the same call — each attempt hanging rather than returning an error it could act on. The turn eventually completed only after the correct `echo '{}' | ...` form was found by trial and error. Nothing in the output ever said "stdin missing".
2. **A teammate hung its own session by invoking the launcher with no subcommand at all.** The same binary is a launcher: called with no subcommand it starts the resident service and never exits, which presents identically from the agent's point of view — "command produced no output and never returns". That case led us to write a rule forbidding bare invocation. We mention it here because it is the same class of failure — **a usage error that presents as a hang instead of an error** — even though the root cause differs from the stdin case.
Both manifest as "command hangs / teammate unreachable", which is how they get misdiagnosed as platform failures.
### Current workaround (works, but does not belong in user rules)
Every role prompt in our organisation now carries a mandatory clause: *always pipe JSON to `team` subcommands, even an empty `{}`; never bare-invoke; never probe with `command -v team`.* This is a documented, effective mitigation — but hundreds of agents are being taught to work around a missing error message, and new teams hit the wall before they read the rule. The root fix belongs platform-side.
### Proposed enhancement
1. **Fail fast on absent/empty stdin.** If stdin is not a TTY and yields no bytes (or stdin is absent), exit immediately with a structured error, e.g.:
```
TEAM_CLI_STDIN_MISSING: `team members` requires a JSON object on stdin; try: echo '{}' | aioncore team members
```
If stdin is a TTY and the user is interactive, a prompt or the same error is still better than a silent wait.
2. **Name the expected shape in the error.** The team CLI already has a `capabilities` command that returns schemas — the fast-fail error should point at it (`aioncore team capabilities`) so an agent can self-correct in one turn instead of guessing.
3. **Consider the same treatment for a missing subcommand.** Invoking the launcher with no subcommand starts the resident service and never exits. If that is intended behaviour, a one-line notice on stderr ("starting resident service, press Ctrl-C to stop") would already prevent agents from reading it as a hang. If it is not intended, an explicit error would be better.
4. **Any bounded wait is better than an unbounded one.** If a bounded read timeout already exists somewhere in this path, surfacing it as an error code rather than a silent kill would be enough to make the failure self-describing.
### Expected Behavior
A usage error returns a non-zero exit code plus a message naming the mistake and the correct invocation, within milliseconds — never an unbounded silent block.
### Impact
- Every agent that calls `team` without piping JSON stalls instead of self-correcting, and misdiagnoses the stall as a teammate or platform failure.
- Organisation-wide prompt rules now exist purely to avoid this one behaviour.
- Real incidents are harder to spot because the most common failure mode looks identical to a hang.
---
### 中文摘要(Chinese summary)
`aioncore team <子命令>` 若不从 stdin 喂 JSON 而裸调,进程会静默阻塞在 `read(stdin)`(实测阻塞约 2 分钟直至被外部超时杀掉),全程无任何提示输出。两位领队在不同机器上独立复现 `aioncore team members` 裸调阻塞。
问题对 **agent 调用方**尤其致命:调用方无法区分「我漏喂 stdin 的用法错误(可立即自纠)」与「平台慢 / 队友失联 / 通道坏了(需上报)」,于是把用法错误当事故上报。
**今日新增受害样本(2026-08-31)**:①本队一名队友初次接单时因未喂 JSON 命中静默阻塞并反复重试同一调用,单次接单白耗约 22 分钟,最终靠试出 `echo '{}' | ...` 才走通,全程没有任何输出说明是 stdin 缺失;②另一名队友不带子命令裸跑该二进制(该二进制同时是启动器,裸跑会拉起常驻服务永不退出),会话直接挂起——从 agent 视角与前者表现完全一致(无输出、不返回)。两者同属「用法错误伪装成卡死」。
现有规避已写进全组织岗位 rule(永远喂 JSON 哪怕是 `{}`、禁裸跑、禁 `command -v team` 探测),有效但属于让数百个 agent 去绕开一条本该存在的报错。
建议:①stdin 缺失/为空立即 fail-fast,报结构化错误如 `TEAM_CLI_STDIN_MISSING`,并给出正确写法示例;②错误里指向 `aioncore team capabilities` 让 agent 一轮内自纠;③无子命令裸跑同样处理——若拉起常驻服务是预期行为,至少在 stderr 提示一行,避免被读成卡死;④任何有界等待都优于无界静默阻塞。
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the `aioncore team` CLI entry point and reproduce `aioncore team members` without stdin, then inspect the `read(stdin)` path and the existing `capabilities` command. Define the intended behavior for missing or empty stdin and for a missing subcommand before changing the relevant handling. Done means a bounded, non-zero response with a structured diagnostic and corrective invocation instead of an unbounded silent block.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100