Skip to content

docs(research): opencode 会话忙闲信号实测 — 修正此前「无状态端点」的假阴性结论 - #471

Merged
vansin merged 1 commit into
mainfrom
docs/opencode-session-signal
Jul 29, 2026
Merged

docs(research): opencode 会话忙闲信号实测 — 修正此前「无状态端点」的假阴性结论#471
vansin merged 1 commit into
mainfrom
docs/opencode-session-signal

Conversation

@vansin

@vansin vansin commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

为什么提这个

opencode 人机共存的拓扑决策一直卡在一个前提上:外部能否知道某个会话正在生成中
此前探测得出的结论是"没有可用的状态端点",据此倾向选择成本较高的方案(自建一层终端仲裁,估 14-20h)。

实测发现这个结论是假阴性,信号一直都在

结论

/event 是一条 SSE 推送流,session.status 事件带 per-session 的 busy / idle 状态。单次生成期间捕获 224 条事件,busy→idle 转换完整。

之前判成"没有"的原因有两条,都属探测方法问题:

  1. 只探了主动查询类端点(这些确实不存在);
  2. 唯一探到 /event 的那次读取超时 2 秒、仅收到 89 字节即断开,没读到流内容。

信号是推送式的,而探测方式是拉取式的,形态不匹配。

同时记录了边界(避免下一个人过度乐观)

该信号只能约束程序自身,约束不了人。同环境下已复现:当第二条消息真正落在第一条的生成窗口内时,两条会被合并为同一条回复(相同 message id、同时返回)。

所以订阅事件的真实价值是"我们自己不制造冲突 + 检测到忙时可提示",而不是"冲突问题解决了"。

复现要点

文档里写了完整复现步骤。其中一条值得强调:验证合并现象时必须先用时间戳证明第二条消息确实落在第一条的生成窗口内——若第一条已结束才发第二条,会得到不同的 message id,从而得出"不会合并"的错误结论(我第一次跑就踩了这个坑)。

纯文档,无代码改动。

/event 是 SSE 推送流, session.status 事件带 per-session 的 busy/idle 状态。
此前判定为「无可用状态端点」是探测方法造成的假阴性:只探了主动查询类
端点, 且抓流时读取超时 2 秒仅收到 89 字节即断开。

同时记录该信号的边界: 它只能约束程序自身, 约束不了人。已复现当第二条
消息真正落在第一条生成窗口内时两条会被合并为同一条回复。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f9a6dfa6c

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# opencode 会话忙闲信号 — 实测记录

日期:2026-07-29
环境:独立服务器(4 核 / 14G,专用于该实验),opencode-ai 1.17.13,免费模型 `opencode/deepseek-v4-flash-free`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Validate the signal against the supported OpenCode pin

When this record is used to choose the M2 co-presence topology, the experiment only establishes behavior for opencode-ai@1.17.13, while agent-network/src/opencode-pin.ts:22 fixes the supported runtime at 1.18.1 and docs/rfcs/RFC-029-opencode-runtime-integration.md:13 explicitly treats 1.17.13 results as historical. Endpoint availability, event schema, and concurrent-turn behavior therefore remain unverified for the version that will actually ship; rerun the probe on 1.18.1 or scope these conclusions as historical rather than using them for the current design decision.

Useful? React with 👍 / 👎.

{"type":"session.status","properties":{"sessionID":"ses_…","status":{"type":"idle"}}}
```

单次生成期间共捕获 224 条事件,类型分布(节选):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the required Docker probe evidence

For the M0 topology decision, the 224-event count and message-merging result exist only as prose: this commit adds no isolated Dockerfile/run script, raw SSE and timestamp dump, or docs/tests/report-testN.txt. This also bypasses the explicit M0 gate in docs/rfcs/RFC-029-opencode-runtime-integration.md:641 requiring a Docker-isolated probe with raw HTTP dumps, so reviewers cannot verify either the event schema or that the two messages actually overlapped; rerun this as an independent Docker suite and retain its raw evidence and report.

AGENTS.md reference: AGENTS.md:L7-L9

Useful? React with 👍 / 👎.

Comment on lines +41 to +42
- 外部程序**可以**订阅 `/event`、按 `sessionID` 跟踪忙闲,从而在会话忙时不发送自己的消息;
- 这使"轻量方案(订阅事件 + 自我串行)"重新可行,无需自建终端仲裁层。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Establish session state when the SSE listener connects

When the daemon starts or reconnects while a session is already busy or idle, this subscription-only design has no demonstrated initial state: the sole procedure at lines 57–59 opens /event before starting generation and therefore validates only future busy→idle transitions. Assuming idle on connection can inject a message into an existing turn, while treating an unknown state as busy can leave an already-idle session queued indefinitely if the stream does not replay a snapshot; probe startup and reconnect during both states and define a snapshot/resynchronization path before concluding that event subscription can replace the arbitration layer.

AGENTS.md reference: AGENTS.md:L5-L6

Useful? React with 👍 / 👎.

## 对共存设计的影响

- 外部程序**可以**订阅 `/event`、按 `sessionID` 跟踪忙闲,从而在会话忙时不发送自己的消息;
- 这使"轻量方案(订阅事件 + 自我串行)"重新可行,无需自建终端仲裁层。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Apply the RFC fallback after reproducing an unarbitrated race

In the actual co-presence scenario where a human turn overlaps an anet turn, the experiment at line 48 demonstrates that OpenCode merges the requests rather than arbitrating them, yet this line concludes that the no-arbiter option is sufficient. That result matches the explicit Option (ii) fallback condition in docs/rfcs/RFC-029-opencode-runtime-integration.md:546—a concurrent race with no arbitration—and an SSE status notification cannot enforce the human lease required at line 500. Either retain the arbiter fallback or formally change the accepted co-presence semantics to allow merged turns; the observed signal alone does not justify the stated topology decision.

Useful? React with 👍 / 👎.

@vansin
vansin merged commit bfd0cc9 into main Jul 29, 2026
1 check passed
@vansin
vansin deleted the docs/opencode-session-signal branch July 29, 2026 00:42
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.

2 participants