work-ally 0.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +110 -0
- package/DASHBOARD.md +160 -0
- package/PRODUCT.md +113 -0
- package/README.md +403 -0
- package/ally.sh +171 -0
- package/bridge/src/approval-rules.ts +360 -0
- package/bridge/src/channel-delivery.ts +207 -0
- package/bridge/src/channel-types.ts +22 -0
- package/bridge/src/channels/fake/adapter.ts +31 -0
- package/bridge/src/channels/feishu/adapter.ts +411 -0
- package/bridge/src/channels/feishu/approvals.ts +6 -0
- package/bridge/src/channels/feishu/formatter.ts +276 -0
- package/bridge/src/channels/feishu/normalize.ts +368 -0
- package/bridge/src/codex-config.ts +52 -0
- package/bridge/src/config.ts +240 -0
- package/bridge/src/fake-runtime-client.ts +505 -0
- package/bridge/src/handoff-service.ts +494 -0
- package/bridge/src/logger.ts +194 -0
- package/bridge/src/memory-digest.ts +186 -0
- package/bridge/src/receiver-approval-autonomy.ts +158 -0
- package/bridge/src/receiver-control-core.ts +140 -0
- package/bridge/src/receiver-control-work-session.ts +218 -0
- package/bridge/src/receiver-control.ts +83 -0
- package/bridge/src/receiver-delivery.ts +136 -0
- package/bridge/src/receiver-helpers.ts +96 -0
- package/bridge/src/receiver-human-gate.ts +333 -0
- package/bridge/src/receiver-inbound-preflight.ts +162 -0
- package/bridge/src/receiver-recovery.ts +236 -0
- package/bridge/src/receiver-runtime-callbacks.ts +367 -0
- package/bridge/src/receiver-runtime-policy.ts +132 -0
- package/bridge/src/receiver-runtime-state.ts +124 -0
- package/bridge/src/receiver-support-actions.ts +189 -0
- package/bridge/src/receiver-thread-start.ts +57 -0
- package/bridge/src/receiver-turn-coordination.ts +94 -0
- package/bridge/src/receiver-turn-execution.ts +257 -0
- package/bridge/src/receiver-turn-failure.ts +143 -0
- package/bridge/src/receiver-turn-result.ts +185 -0
- package/bridge/src/receiver-turn-steer.ts +70 -0
- package/bridge/src/receiver-work-session.ts +76 -0
- package/bridge/src/receiver.ts +329 -0
- package/bridge/src/router.ts +62 -0
- package/bridge/src/runtime-client-agent-messages.ts +150 -0
- package/bridge/src/runtime-client-message-dispatch.ts +176 -0
- package/bridge/src/runtime-client-protocol.ts +411 -0
- package/bridge/src/runtime-client-request-ops.ts +56 -0
- package/bridge/src/runtime-client-run-turn.ts +158 -0
- package/bridge/src/runtime-client-thread-ops.ts +270 -0
- package/bridge/src/runtime-client-transport.ts +309 -0
- package/bridge/src/runtime-client-turn-poll.ts +224 -0
- package/bridge/src/runtime-client-turn-read.ts +185 -0
- package/bridge/src/runtime-client-turn-state.ts +105 -0
- package/bridge/src/runtime-client.ts +344 -0
- package/bridge/src/runtime-user-input.ts +403 -0
- package/bridge/src/scheduler.ts +239 -0
- package/bridge/src/server-handoff-command.ts +364 -0
- package/bridge/src/server-main.ts +80 -0
- package/bridge/src/server-routine-command.ts +60 -0
- package/bridge/src/server-routine-execution.ts +222 -0
- package/bridge/src/server-runtime-app-support.ts +107 -0
- package/bridge/src/server-runtime-app.ts +238 -0
- package/bridge/src/server-thread-sync-command.ts +63 -0
- package/bridge/src/server.ts +17 -0
- package/bridge/src/session-store-delivery.ts +220 -0
- package/bridge/src/session-store-human-gate.ts +380 -0
- package/bridge/src/session-store-inbound-acceptance.ts +66 -0
- package/bridge/src/session-store-meta.ts +134 -0
- package/bridge/src/session-store-turn-ledger.ts +272 -0
- package/bridge/src/session-store.ts +380 -0
- package/bridge/src/system-notify.ts +220 -0
- package/bridge/src/thread-sync.ts +200 -0
- package/bridge/src/translator.ts +494 -0
- package/bridge/src/types.ts +289 -0
- package/bridge/src/utils.ts +104 -0
- package/bridge/src/work-session-store.ts +471 -0
- package/docs/.gitkeep +0 -0
- package/docs/architecture/codex-feishu-bridge-proposal.md +2742 -0
- package/docs/completed/FEATURE-feishu-markdown-and-reply-support.md +327 -0
- package/docs/completed/README.md +21 -0
- package/docs/completed/SPEC-approval-autonomy-and-safe-defaults.md +205 -0
- package/docs/completed/SPEC-approval-batch-and-strict-reply-shortcuts.md +153 -0
- package/docs/completed/SPEC-conversation-noise-reduction-and-busy-input-gate.md +538 -0
- package/docs/completed/SPEC-engineering-sop-skillization.md +190 -0
- package/docs/completed/SPEC-faithful-bridge-core-thinning-v2.md +376 -0
- package/docs/completed/SPEC-faithful-bridge-core-thinning.md +1071 -0
- package/docs/completed/SPEC-group-chat-sender-identity.md +301 -0
- package/docs/completed/SPEC-middleware-exception-visibility.md +227 -0
- package/docs/completed/SPEC-nightly-memory-digest-visibility.md +121 -0
- package/docs/completed/SPEC-project-group-chat-human-centered-conversation-mapping.md +326 -0
- package/docs/completed/SPEC-remove-cli-persona-bootstrap.md +201 -0
- package/docs/developer-workflow.md +49 -0
- package/docs/implementation/SPEC-codex-same-machine-session-handoff-implementation.md +239 -0
- package/docs/implementation/test-coverage-map.md +363 -0
- package/docs/implementation/work-ally-implementation-guide.md +790 -0
- package/docs/issues/README.md +10 -0
- package/docs/issues/pending/ANALYSIS-ally-premature-recovery-notice-and-task-state-semantics-2026-03-18.md +295 -0
- package/docs/issues/resolved/ANALYSIS-approval-waiting-visible-but-approval-artifact-missing-2026-03-16.md +466 -0
- package/docs/issues/resolved/ANALYSIS-blocking-state-visible-without-user-actionable-artifact-2026-03-16.md +261 -0
- package/docs/issues/resolved/ANALYSIS-codex-app-server-transport-disconnect-semantics-2026-03-14.md +606 -0
- package/docs/issues/resolved/ANALYSIS-premature-terminalization-on-fresh-thread-poll-and-object-error-leak-2026-03-16.md +348 -0
- package/docs/issues/resolved/ANALYSIS-runtime-turn-delivery-and-recovery-2026-03-14.md +603 -0
- package/docs/issues/resolved/ANALYSIS-self-test-gap-approval-waiting-visible-but-approval-artifact-missing-2026-03-16.md +166 -0
- package/docs/issues/resolved/ANALYSIS-self-test-gap-blocking-state-visible-without-user-actionable-artifact-2026-03-16.md +186 -0
- package/docs/issues/resolved/ANALYSIS-self-test-gap-premature-terminalization-on-fresh-thread-poll-and-object-error-leak-2026-03-16.md +166 -0
- package/docs/issues/resolved/REPORT-ally-runtime-turn-delivery-3b42fb8-2026-03-15.md +373 -0
- package/docs/manual-acceptance.md +127 -0
- package/docs/ops-runbook.md +44 -0
- package/docs/planning/FEATURE-memory-system.md +748 -0
- package/docs/planning/SPEC-active-turn-steer-and-context-compaction-visibility.md +269 -0
- package/docs/planning/SPEC-approval-rules-inheritance-and-local-validation-lane.md +450 -0
- package/docs/planning/SPEC-assistant-persona-bootstrap.md +199 -0
- package/docs/planning/SPEC-assistant-rename.md +610 -0
- package/docs/planning/SPEC-bridge-app-server-protocol-alignment.md +667 -0
- package/docs/planning/SPEC-claude-runtime-host-for-work-ally.md +434 -0
- package/docs/planning/SPEC-cli-feishu-codex-session-unification.md +236 -0
- package/docs/planning/SPEC-codex-same-machine-session-handoff.md +873 -0
- package/docs/planning/SPEC-feishu-reaction-shortcuts.md +282 -0
- package/docs/planning/SPEC-local-stable-release-boundary.md +166 -0
- package/docs/planning/SPEC-managed-thread-entry-and-surface-mobility.md +862 -0
- package/docs/planning/SPEC-minimal-bridge-semantics-and-user-visible-surface.md +362 -0
- package/docs/planning/SPEC-npm-alpha-distribution-and-install-first-release.md +222 -0
- package/docs/planning/SPEC-remove-websocket-runtime-transport.md +364 -0
- package/docs/planning/SPEC-runtime-abstraction-phase-1.md +424 -0
- package/docs/planning/SPEC-runtime-connection-and-turn-recovery-semantics.md +274 -0
- package/docs/planning/SPEC-session-presence-and-state-visibility.md +397 -0
- package/docs/planning/SPEC-skill-first-capability-packaging.md +338 -0
- package/docs/planning/SPEC-stable-archive-contract.md +456 -0
- package/docs/planning/SPEC-supervised-start-boundary.md +127 -0
- package/docs/planning/SPEC-user-barrier-reduction-and-activation.md +832 -0
- package/docs/planning/ally-next.md +1278 -0
- package/docs/planning/assistant-workbench-spec.md +725 -0
- package/docs/planning/product-workbench.md +283 -0
- package/docs/product-onboarding.md +227 -0
- package/docs/product-spec-standard.md +528 -0
- package/docs/troubleshooting.md +45 -0
- package/docs/user-quickstart.md +46 -0
- package/internal/dispatch.sh +95 -0
- package/internal/lib/common.sh +1450 -0
- package/internal/modules/assistant/manage.sh +1312 -0
- package/internal/modules/bootstrap/setup.sh +144 -0
- package/internal/modules/config/init-env.sh +10 -0
- package/internal/modules/global/manage.sh +154 -0
- package/internal/modules/handoff/manage.sh +54 -0
- package/internal/modules/mcp/manage.sh +83 -0
- package/internal/modules/ops/logs.sh +76 -0
- package/internal/modules/routines/manage.sh +55 -0
- package/internal/modules/runtime/assistant-autosave.sh +26 -0
- package/internal/modules/runtime/restart.sh +6 -0
- package/internal/modules/runtime/start.sh +283 -0
- package/internal/modules/runtime/status.sh +194 -0
- package/internal/modules/runtime/stop.sh +55 -0
- package/internal/modules/runtime/supervisor.sh +216 -0
- package/internal/modules/runtime/update.sh +26 -0
- package/package.json +41 -0
- package/runtime/config/.gitkeep +0 -0
- package/runtime/host/.gitkeep +0 -0
- package/runtime/host/healthcheck-codex-app-server.ts +22 -0
- package/runtime/host/ping-pong-codex-app-server.ts +66 -0
- package/runtime/host/probe-codex-app-server.ts +115 -0
- package/skills/archive-reader/SKILL.md +9 -0
- package/skills/feishu-production-debug/SKILL.md +37 -0
- package/skills/feishu-production-debug/references/feishu-debug-order.md +49 -0
- package/skills/feishu-production-debug/references/platform-permission-baseline.md +23 -0
- package/skills/issue-to-spec-triage/SKILL.md +44 -0
- package/skills/issue-to-spec-triage/references/triage-rules.md +66 -0
- package/skills/memory-digest/SKILL.md +9 -0
- package/skills/post-implementation-closure/SKILL.md +39 -0
- package/skills/post-implementation-closure/references/closure-checklist.md +45 -0
- package/skills/post-implementation-closure/references/doc-drift-map.md +49 -0
- package/skills/product-spec/SKILL.md +244 -0
- package/templates/env.example +5 -0
- package/templates/routines/nightly-memory-digest.yaml +10 -0
- package/templates/workspace/AGENTS.md +26 -0
|
@@ -0,0 +1,667 @@
|
|
|
1
|
+
# SPEC: Bridge App Server Protocol Alignment
|
|
2
|
+
|
|
3
|
+
更新时间:2026-03-17
|
|
4
|
+
状态:Ready for implementation
|
|
5
|
+
Owner:work-ally engineering
|
|
6
|
+
相关文档:
|
|
7
|
+
- `docs/planning/SPEC-runtime-connection-and-turn-recovery-semantics.md`
|
|
8
|
+
- `docs/planning/SPEC-session-presence-and-state-visibility.md`
|
|
9
|
+
- `docs/issues/resolved/ANALYSIS-runtime-turn-delivery-and-recovery-2026-03-14.md`
|
|
10
|
+
- `docs/issues/resolved/ANALYSIS-codex-app-server-transport-disconnect-semantics-2026-03-14.md`
|
|
11
|
+
- `docs/issues/resolved/REPORT-ally-runtime-turn-delivery-3b42fb8-2026-03-15.md`
|
|
12
|
+
|
|
13
|
+
## 1. Summary
|
|
14
|
+
|
|
15
|
+
这份 spec 不是再补一个“断连恢复” patch,而是把 `work-ally` 的 bridge 重新收回到正确边界:
|
|
16
|
+
|
|
17
|
+
> bridge 不是任务裁判,也不是第二个 agent;它应该是 **Codex App Server 协议事实的转发器 + 最小编排器**。
|
|
18
|
+
|
|
19
|
+
当前稳定性问题的根因,已经不再应理解成“Codex 经常不稳定”,而应理解成:
|
|
20
|
+
|
|
21
|
+
1. 我们的 bridge 还保留了一层自定义的任务语义
|
|
22
|
+
2. 这层语义与官方 App Server 原语并不完全一致
|
|
23
|
+
3. 一旦 transport 抖动、waiting request、迟到终态或用户追问叠在一起,bridge 就会替用户过早下结论,导致消息没正确转给 Codex,或 Codex 的真实结果没被稳定转回来
|
|
24
|
+
|
|
25
|
+
本次要做的,是一次协议对齐型重构:
|
|
26
|
+
|
|
27
|
+
1. 普通自然语言输入回归 `turn/start` / `turn/steer` 主路径
|
|
28
|
+
2. `waitingOnApproval` / `waitingOnUserInput` 回归线程事实,而不是 bridge 主观阻塞结论
|
|
29
|
+
3. 最终结果继续坚持 `pull-primary`
|
|
30
|
+
4. transport 生命周期降回内部可观测性,不再直接翻译成任务终态
|
|
31
|
+
5. 只有 slash 命令和明确的 approval / user-input 回答,才由 bridge 本地消费
|
|
32
|
+
|
|
33
|
+
这份 spec 写完之后,未来的实现工作应直接按本文件推进,而不是继续依赖“记得之前聊过什么”。
|
|
34
|
+
|
|
35
|
+
## 2. 背景
|
|
36
|
+
|
|
37
|
+
目前我们已经做过几轮稳定性修复,收住了几件重要事情:
|
|
38
|
+
|
|
39
|
+
1. 最终结果已经切到 `pull-primary`
|
|
40
|
+
2. `turn/completed` 不再是唯一真相
|
|
41
|
+
3. inbound / turn / delivery ledger 已经建立最小台账
|
|
42
|
+
4. waiting artifact 是否已真正可见,已经进入状态判断
|
|
43
|
+
|
|
44
|
+
这些工作是正确方向,但它们还没有彻底解决一个更根本的问题:
|
|
45
|
+
|
|
46
|
+
> bridge 仍然在协议事实之上,额外创造了一层“本地任务语义”。
|
|
47
|
+
|
|
48
|
+
这层语义主要体现在:
|
|
49
|
+
|
|
50
|
+
1. busy 时,普通自然语言会被本地拦截,而不是优先回到协议原语
|
|
51
|
+
2. waiting 时,bridge 可能先根据 thread flag 自己认定“现在不能转给 Codex”
|
|
52
|
+
3. 某些终态会被 bridge 翻译成 `当前任务已停止`、`当前已暂停`、`请重发` 等结论性语言
|
|
53
|
+
4. transport 生命周期、任务状态、用户可见状态,这三层仍然存在混淆
|
|
54
|
+
|
|
55
|
+
这就是为什么用户会体感到:
|
|
56
|
+
|
|
57
|
+
1. 我的话到底有没有传给 Codex,不确定
|
|
58
|
+
2. Codex 明明已经继续工作了,但飞书前面看不到结果
|
|
59
|
+
3. assistant 明明只是卡在 approval / user input,可用户前面像“人没了”
|
|
60
|
+
4. 中间层表现得像在“帮我判断真相”,而不是在“老老实实转发真相”
|
|
61
|
+
|
|
62
|
+
## 3. 问题定义
|
|
63
|
+
|
|
64
|
+
当前问题不是单点 bug,而是 4 类系统性偏差。
|
|
65
|
+
|
|
66
|
+
### 3.1 输入路由偏差
|
|
67
|
+
|
|
68
|
+
除 slash 命令外,飞书用户的输入本应默认属于“发给 Codex”。
|
|
69
|
+
|
|
70
|
+
但当前 bridge 仍会在某些 busy / waiting 场景下,先做本地拦截和本地解释。这会导致两个问题:
|
|
71
|
+
|
|
72
|
+
1. 用户以为自己在追问 Codex,实际却在和中间层对话
|
|
73
|
+
2. bridge 一旦判断错,就会把用户输入吞在自己这里
|
|
74
|
+
|
|
75
|
+
### 3.2 waiting 语义偏差
|
|
76
|
+
|
|
77
|
+
`waitingOnApproval` / `waitingOnUserInput` 是 runtime thread 的事实,不等于“用户前台已经拿到了可操作实体”。
|
|
78
|
+
|
|
79
|
+
当前系统虽然已经开始区分“flag visible”与“artifact visible”,但整体语义仍未完全收口:
|
|
80
|
+
|
|
81
|
+
1. waiting 是线程事实
|
|
82
|
+
2. blocking 是用户视角事实
|
|
83
|
+
3. 只有当 approval card / user-input prompt 已稳定送达时,bridge 才能说“当前轮到你了”
|
|
84
|
+
|
|
85
|
+
### 3.3 终态语义偏差
|
|
86
|
+
|
|
87
|
+
bridge 仍然在一些路径上替用户下结论,例如:
|
|
88
|
+
|
|
89
|
+
1. `当前任务已停止`
|
|
90
|
+
2. `当前已暂停`
|
|
91
|
+
3. `请重发上一条`
|
|
92
|
+
|
|
93
|
+
其中有些是合理的产品翻译,有些则属于过度推断。
|
|
94
|
+
|
|
95
|
+
正确边界应该是:
|
|
96
|
+
|
|
97
|
+
1. `/stop` 触发的明确中断,才可以稳定翻译成“已停止”
|
|
98
|
+
2. 其他 interrupted / transport failure / final-state unconfirmed,都只是事实不足,不该被 bridge 翻译成“任务就这样结束了”
|
|
99
|
+
3. 只要终态还可继续对账,bridge 就不应过早终止用户理解
|
|
100
|
+
|
|
101
|
+
### 3.4 传输层与任务层混淆
|
|
102
|
+
|
|
103
|
+
官方 App Server 给的是协议原语和线程事实,不要求客户端把 transport 生命周期直接上升成任务语义。
|
|
104
|
+
|
|
105
|
+
当前 bridge 虽然已经比以前克制,但整体设计上仍受到“在线 push 事件驱动 UI 语义”的影响。
|
|
106
|
+
|
|
107
|
+
这会带来两个后果:
|
|
108
|
+
|
|
109
|
+
1. 容易把 transport 抖动误读成任务失败
|
|
110
|
+
2. 容易把在线事件缺失误读成 turn 不存在或任务没继续
|
|
111
|
+
|
|
112
|
+
## 4. 为什么现在做
|
|
113
|
+
|
|
114
|
+
现在必须做,不适合继续拖。
|
|
115
|
+
|
|
116
|
+
原因有四个:
|
|
117
|
+
|
|
118
|
+
1. 这已经不是一个“体验小瑕疵”,而是在损伤产品最核心的可信度
|
|
119
|
+
2. 现在已经有足够多事故和证据,问题边界已比较清楚,再继续打补丁只会让状态机更脏
|
|
120
|
+
3. 当前产品已经进入内部多人、多 assistant、长期打磨阶段,中间层语义如果不收干净,后续所有 feature 都会建立在错误地基上
|
|
121
|
+
4. 这件事如果拖到更晚再做,后面要兼容的行为和文档只会更多,返工成本会更高
|
|
122
|
+
|
|
123
|
+
## 5. 目标
|
|
124
|
+
|
|
125
|
+
本次重构必须达成下面 8 个目标。
|
|
126
|
+
|
|
127
|
+
1. 普通自然语言输入默认回归 Codex,而不是默认被 bridge 私自吞掉
|
|
128
|
+
2. `turn/start` / `turn/steer` / `turn/interrupt` 成为输入控制主骨架
|
|
129
|
+
3. `waitingOnApproval` / `waitingOnUserInput` 只表达线程事实,不直接等价于用户阻塞事实
|
|
130
|
+
4. approval / user-input 只有在可操作实体已可见时,才进入真正 blocking 状态
|
|
131
|
+
5. 最终结果继续以 `thread/read(includeTurns=true)` 为 pull-primary 真相源
|
|
132
|
+
6. transport 生命周期彻底降级为内部可观测性,不再直接驱动用户任务结论
|
|
133
|
+
7. `当前任务已停止` 这类强结论文案只保留在明确 `/stop` 语义内
|
|
134
|
+
8. 测试门禁按协议矩阵重排,避免以后再按症状补 case
|
|
135
|
+
|
|
136
|
+
## 6. 非目标
|
|
137
|
+
|
|
138
|
+
这次明确不做:
|
|
139
|
+
|
|
140
|
+
1. 不在本期把 transport 从 websocket 直接切到 stdio
|
|
141
|
+
2. 不重做 Codex runtime host
|
|
142
|
+
3. 不做新的 dashboard / GUI 运维面板
|
|
143
|
+
4. 不做 exactly-once 分布式协议
|
|
144
|
+
5. 不做 approval / user-input 的完全离线重放协议
|
|
145
|
+
6. 不把 threadId / turnId 暴露给普通飞书用户
|
|
146
|
+
7. 不在本期引入复杂队列系统或任务编排引擎
|
|
147
|
+
|
|
148
|
+
说明:
|
|
149
|
+
|
|
150
|
+
`stdio` 方向是值得考虑的,但那是独立运输层专题;本 spec 先解决“即便 transport 有波动,bridge 也不能误判任务语义”这个更核心的问题。
|
|
151
|
+
|
|
152
|
+
## 7. 官方协议对齐判断
|
|
153
|
+
|
|
154
|
+
本次重构只认下面这些官方事实。
|
|
155
|
+
|
|
156
|
+
### 7.1 协议与传输
|
|
157
|
+
|
|
158
|
+
1. App Server 是双向 JSON-RPC 协议
|
|
159
|
+
2. 官方默认传输是 `stdio`
|
|
160
|
+
3. `websocket` 在官方文档里仍是 experimental transport
|
|
161
|
+
4. 客户端应围绕协议原语和线程事实构建 UI,而不是自行脑补第二套真相
|
|
162
|
+
|
|
163
|
+
### 7.2 输入控制原语
|
|
164
|
+
|
|
165
|
+
App Server 已给出 3 个关键输入控制原语:
|
|
166
|
+
|
|
167
|
+
1. `turn/start`:开始新 turn
|
|
168
|
+
2. `turn/steer`:向当前 in-flight turn 追加新的用户输入
|
|
169
|
+
3. `turn/interrupt`:显式打断当前 turn
|
|
170
|
+
|
|
171
|
+
### 7.3 线程状态事实
|
|
172
|
+
|
|
173
|
+
App Server 已给出线程状态事件:
|
|
174
|
+
|
|
175
|
+
1. `thread/status/changed`
|
|
176
|
+
2. `activeFlags` 包括 `waitingOnApproval` / `waitingOnUserInput`
|
|
177
|
+
|
|
178
|
+
### 7.4 审批事实
|
|
179
|
+
|
|
180
|
+
App Server 会主动向客户端发起审批请求:
|
|
181
|
+
|
|
182
|
+
1. `item/commandExecution/requestApproval`
|
|
183
|
+
2. `item/fileChange/requestApproval`
|
|
184
|
+
3. `serverRequest/resolved` 表示待处理请求已被回答或清除
|
|
185
|
+
|
|
186
|
+
因此 bridge 的边界应该是:
|
|
187
|
+
|
|
188
|
+
1. 接住这些协议事实
|
|
189
|
+
2. 把它们翻译成用户能理解的最小产品语义
|
|
190
|
+
3. 绝不把它们改写成 bridge 自己想象的另一个任务世界
|
|
191
|
+
|
|
192
|
+
## 8. 产品定义与用户路径
|
|
193
|
+
|
|
194
|
+
### 8.1 一句话产品定义
|
|
195
|
+
|
|
196
|
+
本次重构后,`work-ally` 的 bridge 应表现为:
|
|
197
|
+
|
|
198
|
+
> 除 slash 命令外,用户发给飞书的内容默认都是发给 Codex;bridge 只负责把协议事实稳定送进去,再把 Codex 的真实状态和结果稳定带回来。
|
|
199
|
+
|
|
200
|
+
### 8.2 输入分类
|
|
201
|
+
|
|
202
|
+
V1 只保留三类输入路径。
|
|
203
|
+
|
|
204
|
+
#### A. 本地控制命令
|
|
205
|
+
|
|
206
|
+
仍由 bridge 本地消费:
|
|
207
|
+
|
|
208
|
+
- `/status`
|
|
209
|
+
- `/stop`
|
|
210
|
+
- `/new`
|
|
211
|
+
- `/approve`
|
|
212
|
+
- `/deny`
|
|
213
|
+
- 其他明确 slash 控制命令
|
|
214
|
+
|
|
215
|
+
#### B. Pending request 的直接回答
|
|
216
|
+
|
|
217
|
+
当已经存在 **用户可见** 的 approval / user-input 请求时:
|
|
218
|
+
|
|
219
|
+
1. 用户直接回复 `同意` / `拒绝` / 选项 / 表单答案
|
|
220
|
+
2. bridge 将其解释为对当前 pending request 的回答
|
|
221
|
+
3. 回答仍然要写回 Codex runtime
|
|
222
|
+
|
|
223
|
+
这类输入不是“bridge 吞掉了用户的话”,而是 bridge 在履行协议里的 request/response 责任。
|
|
224
|
+
|
|
225
|
+
#### C. 其他普通自然语言
|
|
226
|
+
|
|
227
|
+
其余所有非 slash 文本,默认都视为要转给 Codex。
|
|
228
|
+
|
|
229
|
+
默认路由规则:
|
|
230
|
+
|
|
231
|
+
1. 当前无 active turn:`turn/start`
|
|
232
|
+
2. 当前有 active turn 且没有 unresolved blocking request:`turn/steer`
|
|
233
|
+
3. 当前有 unresolved blocking request:不新建本地任务,不假装“已经转发给 Codex”,而是明确告诉用户“当前正在等你处理这个 request;先完成它,这轮才能继续”
|
|
234
|
+
|
|
235
|
+
这里最关键的约束是:
|
|
236
|
+
|
|
237
|
+
> bridge 只在“官方协议本身明确要求先回答 pending request”时阻塞普通文本,而不是再发明额外的 busy gate 规则。
|
|
238
|
+
|
|
239
|
+
### 8.3 用户主路径
|
|
240
|
+
|
|
241
|
+
#### 路径 1:空闲线程中的普通提问
|
|
242
|
+
|
|
243
|
+
1. 用户发消息
|
|
244
|
+
2. bridge ack
|
|
245
|
+
3. `turn/start`
|
|
246
|
+
4. 结果以 pull-primary 收口
|
|
247
|
+
5. 最终回复回到飞书
|
|
248
|
+
|
|
249
|
+
#### 路径 2:active turn 中的追问 / 补充
|
|
250
|
+
|
|
251
|
+
1. 用户发普通文本
|
|
252
|
+
2. bridge 不本地吃掉
|
|
253
|
+
3. 若线程可继续接受输入,则走 `turn/steer`
|
|
254
|
+
4. Codex 在同一 turn 内继续处理
|
|
255
|
+
|
|
256
|
+
#### 路径 3:approval / user-input 阻塞中
|
|
257
|
+
|
|
258
|
+
1. runtime 发出 request
|
|
259
|
+
2. bridge 先把可操作实体送达给用户
|
|
260
|
+
3. 只有送达成功后,bridge 才进入 blocking waiting 状态
|
|
261
|
+
4. 用户若直接回答该 request,则 bridge resolve 给 runtime
|
|
262
|
+
5. 用户若发的是其他普通文本,则 bridge 明确说明“当前卡在这个 request 上”,但不把这条文本伪装成已转给 Codex
|
|
263
|
+
|
|
264
|
+
#### 路径 4:用户显式停止
|
|
265
|
+
|
|
266
|
+
1. 用户发 `/stop`
|
|
267
|
+
2. bridge 走 `turn/interrupt`
|
|
268
|
+
3. 只有当该 turn 确实以用户停止语义结束时,才向用户显示 `当前任务已停止。`
|
|
269
|
+
|
|
270
|
+
#### 路径 5:transport 抖动 / 在线事件缺失
|
|
271
|
+
|
|
272
|
+
1. 不直接向用户宣布 transport 层事件
|
|
273
|
+
2. turn 终态继续靠 pull-primary 对账
|
|
274
|
+
3. 若终态已存在,补发结果
|
|
275
|
+
4. 若终态仍无法确认,再进入 recovery-required 用户解释路径
|
|
276
|
+
|
|
277
|
+
## 9. 机制设计
|
|
278
|
+
|
|
279
|
+
## 9.1 三层事实模型
|
|
280
|
+
|
|
281
|
+
本次明确把状态分成 3 层,不再混读。
|
|
282
|
+
|
|
283
|
+
### A. Protocol fact
|
|
284
|
+
|
|
285
|
+
来自 App Server 的原始事实:
|
|
286
|
+
|
|
287
|
+
- `turn/start` result
|
|
288
|
+
- `turn/steer` result
|
|
289
|
+
- `turn/interrupt` result
|
|
290
|
+
- `thread/status/changed`
|
|
291
|
+
- `turn/completed`
|
|
292
|
+
- `thread/read(includeTurns=true)`
|
|
293
|
+
- `item/*/requestApproval`
|
|
294
|
+
- `item/tool/requestUserInput`
|
|
295
|
+
- `mcpServer/elicitation/request`
|
|
296
|
+
- `serverRequest/resolved`
|
|
297
|
+
|
|
298
|
+
### B. Bridge ledger fact
|
|
299
|
+
|
|
300
|
+
bridge 在本地持久化的已知事实:
|
|
301
|
+
|
|
302
|
+
- inbound receipt / acceptance
|
|
303
|
+
- current thread / active turn binding
|
|
304
|
+
- visible approval / visible user-input request
|
|
305
|
+
- terminal result persisted
|
|
306
|
+
- delivery delivered / delivery_unavailable / suppressed
|
|
307
|
+
- superseded
|
|
308
|
+
|
|
309
|
+
### C. User-visible semantic
|
|
310
|
+
|
|
311
|
+
只有在前两层都支持的前提下,bridge 才能对用户说:
|
|
312
|
+
|
|
313
|
+
- 正在处理
|
|
314
|
+
- 当前等你审批
|
|
315
|
+
- 当前等你回复
|
|
316
|
+
- 本轮已停止
|
|
317
|
+
- 本轮结果暂未确认
|
|
318
|
+
|
|
319
|
+
原则:
|
|
320
|
+
|
|
321
|
+
> 用户语义只能从协议事实和账本事实推出,不能从 bridge 的主观猜测推出。
|
|
322
|
+
|
|
323
|
+
## 9.2 输入路由状态机
|
|
324
|
+
|
|
325
|
+
### Idle
|
|
326
|
+
|
|
327
|
+
- 普通文本 -> `turn/start`
|
|
328
|
+
- slash -> 本地控制
|
|
329
|
+
|
|
330
|
+
### Active / Steerable
|
|
331
|
+
|
|
332
|
+
满足条件:
|
|
333
|
+
|
|
334
|
+
1. session 有 `threadId + activeTurnId`
|
|
335
|
+
2. 不存在 unresolved visible approval / user-input request
|
|
336
|
+
3. runtime 线程仍 active,或至少未被 pull-primary / ledger 证明终结
|
|
337
|
+
|
|
338
|
+
行为:
|
|
339
|
+
|
|
340
|
+
- 普通文本 -> `turn/steer(expectedTurnId=activeTurnId)`
|
|
341
|
+
- slash `/stop` -> `turn/interrupt`
|
|
342
|
+
- slash 其他命令 -> 本地控制
|
|
343
|
+
|
|
344
|
+
### Active / Waiting on visible request
|
|
345
|
+
|
|
346
|
+
满足条件:
|
|
347
|
+
|
|
348
|
+
1. runtime 显示 waiting flag
|
|
349
|
+
2. 且该 approval / user-input 实体已对用户稳定可见
|
|
350
|
+
|
|
351
|
+
行为:
|
|
352
|
+
|
|
353
|
+
- 对 request 的直接回答 -> resolve request
|
|
354
|
+
- 其他普通文本 -> 明确告知当前正等待该 request,不伪装为已转给 Codex
|
|
355
|
+
- 不再额外套 busy gate 文案体系
|
|
356
|
+
|
|
357
|
+
### Active / Flag visible but artifact not yet visible
|
|
358
|
+
|
|
359
|
+
满足条件:
|
|
360
|
+
|
|
361
|
+
1. runtime waiting flag 已出现
|
|
362
|
+
2. 但 approval card / prompt 尚未稳定送达
|
|
363
|
+
|
|
364
|
+
行为:
|
|
365
|
+
|
|
366
|
+
1. 这时不能说“当前轮到你了”
|
|
367
|
+
2. 也不能永久阻塞后续输入
|
|
368
|
+
3. 先把 request 视为 `pending_visibility`
|
|
369
|
+
4. 只有一旦 artifact 送达成功,才升级成真正 blocking
|
|
370
|
+
|
|
371
|
+
## 9.3 waiting 可见性模型
|
|
372
|
+
|
|
373
|
+
approval / user-input 记录统一加一个可见性维度。
|
|
374
|
+
|
|
375
|
+
建议状态:
|
|
376
|
+
|
|
377
|
+
- `pending_visibility`
|
|
378
|
+
- `visible`
|
|
379
|
+
- `resolved`
|
|
380
|
+
- `failed_visibility`
|
|
381
|
+
|
|
382
|
+
约束:
|
|
383
|
+
|
|
384
|
+
1. runtime thread flag 只决定“Codex 当前正在等什么”
|
|
385
|
+
2. 用户是否真的被阻塞,取决于该 request 是否已经 `visible`
|
|
386
|
+
3. `failed_visibility` 不能长期把会话锁死;要么重投,要么明确降级处理
|
|
387
|
+
|
|
388
|
+
## 9.4 终态模型
|
|
389
|
+
|
|
390
|
+
### 终态真相
|
|
391
|
+
|
|
392
|
+
继续保持:
|
|
393
|
+
|
|
394
|
+
1. `thread/read(includeTurns=true)` 是最终真相主来源
|
|
395
|
+
2. `turn/completed` 是 fast-path,不是唯一真相
|
|
396
|
+
|
|
397
|
+
### 可对用户说“已停止”的唯一条件
|
|
398
|
+
|
|
399
|
+
只在下面条件同时成立时:
|
|
400
|
+
|
|
401
|
+
1. 本次停止来自用户显式 `/stop`
|
|
402
|
+
2. 该 turn 确实被 `turn/interrupt` 针对
|
|
403
|
+
3. 终态与该 stop 请求可对应
|
|
404
|
+
|
|
405
|
+
除此之外:
|
|
406
|
+
|
|
407
|
+
- interrupted + 无 reply:默认不是“已停止”,而是“本轮状态未确认”或 recovery path
|
|
408
|
+
- transport 抖动:不是“已停止”
|
|
409
|
+
- 在线事件缺失:不是“已停止”
|
|
410
|
+
|
|
411
|
+
### Non-completed but reply exists
|
|
412
|
+
|
|
413
|
+
如果 turn 非 completed,但已经有可见 reply:
|
|
414
|
+
|
|
415
|
+
1. reply 优先交付
|
|
416
|
+
2. bridge 不再用本地状态文案盖掉真实 reply
|
|
417
|
+
|
|
418
|
+
## 9.5 Transport 语义模型
|
|
419
|
+
|
|
420
|
+
transport 生命周期从产品层退回实现层。
|
|
421
|
+
|
|
422
|
+
规则:
|
|
423
|
+
|
|
424
|
+
1. runtime / channel 的 connect / disconnect / reconnect 默认不直接面向用户出声
|
|
425
|
+
2. 只有当它们影响到任务事实,才通过任务语义折射给用户
|
|
426
|
+
3. `connection != task`
|
|
427
|
+
4. `reconnected != task resumed`
|
|
428
|
+
|
|
429
|
+
说明:
|
|
430
|
+
|
|
431
|
+
如果未来单独做 `stdio` 迁移,应在 transport spec 中推进;本 spec 先确保即使 transport 继续保留 websocket,任务语义也不再被 transport 误导。
|
|
432
|
+
|
|
433
|
+
## 9.6 Slash 命令边界
|
|
434
|
+
|
|
435
|
+
本次进一步明确:
|
|
436
|
+
|
|
437
|
+
1. slash 是 bridge 与用户的本地协定
|
|
438
|
+
2. 非 slash 文本默认不是 bridge 的 command surface
|
|
439
|
+
3. bridge 不应把普通自然语言当成本地工作流按钮来吞掉
|
|
440
|
+
|
|
441
|
+
## 10. 需要修改的模块
|
|
442
|
+
|
|
443
|
+
### 10.1 `bridge/src/runtime-client.ts`
|
|
444
|
+
|
|
445
|
+
目标:把 runtime client 收回协议原语层。
|
|
446
|
+
|
|
447
|
+
必须补齐或调整:
|
|
448
|
+
|
|
449
|
+
1. 增加 `turn/steer` 客户端接口
|
|
450
|
+
2. 明确 `turn/start` / `turn/steer` / `turn/interrupt` 的错误归一化
|
|
451
|
+
3. `serverRequest/resolved` 进入本地事件流,用来清理 pending request
|
|
452
|
+
4. `thread/status/changed` 继续只作为线程事实缓存,不上升成最终任务结论
|
|
453
|
+
5. 保持 `pull-primary` 终态收口不回退
|
|
454
|
+
|
|
455
|
+
### 10.2 `bridge/src/receiver.ts`
|
|
456
|
+
|
|
457
|
+
目标:删掉过厚的本地任务判定,让输入路由和状态语义都回归协议边界。
|
|
458
|
+
|
|
459
|
+
必须调整:
|
|
460
|
+
|
|
461
|
+
1. 重新定义非 slash 文本的主路由
|
|
462
|
+
2. 把现有 busy gate 从“默认拦截自然语言”改成“只有协议明确 blocking request 时才拦截”
|
|
463
|
+
3. waiting follow-up 逻辑改成基于 visible artifact,而不是仅基于 runtime flag
|
|
464
|
+
4. `当前任务已停止` 只保留 `/stop` 确认路径
|
|
465
|
+
5. 其他 interrupted / recovery-required / unconfirmed 统一回到事实型文案
|
|
466
|
+
|
|
467
|
+
### 10.3 `bridge/src/session-store.ts`
|
|
468
|
+
|
|
469
|
+
目标:把 visible request、turn routing、delivery fact 再收清楚。
|
|
470
|
+
|
|
471
|
+
需要补齐:
|
|
472
|
+
|
|
473
|
+
1. approval / user-input 的 visibility state
|
|
474
|
+
2. active turn 是否 steerable 的最小账本支持
|
|
475
|
+
3. stop 请求与 turn 的对应关系
|
|
476
|
+
4. stale / superseded 后的 active turn 清理逻辑
|
|
477
|
+
|
|
478
|
+
### 10.4 `bridge/src/translator.ts`
|
|
479
|
+
|
|
480
|
+
目标:收口用户语义,而不是继续扩工程内部状态文案。
|
|
481
|
+
|
|
482
|
+
需要调整:
|
|
483
|
+
|
|
484
|
+
1. 删除或弱化不必要的“任务停止/暂停”强结论文案
|
|
485
|
+
2. 明确哪些文案是 slash 控制结果
|
|
486
|
+
3. 明确哪些文案是协议 blocking request 的用户翻译
|
|
487
|
+
4. 避免把 transport 实现术语再次暴露给用户
|
|
488
|
+
|
|
489
|
+
### 10.5 测试体系
|
|
490
|
+
|
|
491
|
+
目标:按协议矩阵重排,而不是继续按症状堆 case。
|
|
492
|
+
|
|
493
|
+
## 11. 子任务拆解
|
|
494
|
+
|
|
495
|
+
### Task A:Runtime protocol surface 对齐
|
|
496
|
+
|
|
497
|
+
目标:让 runtime client 成为纯协议绑定层。
|
|
498
|
+
|
|
499
|
+
DoD:
|
|
500
|
+
|
|
501
|
+
- [ ] 有 `turn/steer` 明确接口
|
|
502
|
+
- [ ] `turn/start / steer / interrupt` 错误归一化一致
|
|
503
|
+
- [ ] `serverRequest/resolved` 可被消费
|
|
504
|
+
- [ ] 单元测试覆盖 start / steer / interrupt / resolved
|
|
505
|
+
|
|
506
|
+
### Task B:输入路由状态机重构
|
|
507
|
+
|
|
508
|
+
目标:非 slash 文本默认回归 Codex。
|
|
509
|
+
|
|
510
|
+
DoD:
|
|
511
|
+
|
|
512
|
+
- [ ] idle 文本走 `turn/start`
|
|
513
|
+
- [ ] active 且 steerable 的文本走 `turn/steer`
|
|
514
|
+
- [ ] 只有 unresolved visible request 时才阻塞普通文本
|
|
515
|
+
- [ ] 不再存在“bridge 自创 busy gate 抢先拦截普通追问”的默认行为
|
|
516
|
+
|
|
517
|
+
### Task C:waiting visibility 模型收口
|
|
518
|
+
|
|
519
|
+
目标:把 waiting 事实和 blocking 事实分开。
|
|
520
|
+
|
|
521
|
+
DoD:
|
|
522
|
+
|
|
523
|
+
- [ ] approval / user-input 具有 visibility state
|
|
524
|
+
- [ ] runtime waiting flag 但 artifact 不可见时,不会把会话永久锁死
|
|
525
|
+
- [ ] artifact visible 后,阻塞解释一致
|
|
526
|
+
- [ ] `serverRequest/resolved` 或本地 resolve 后,blocking 状态清除
|
|
527
|
+
|
|
528
|
+
### Task D:终态与用户语义收口
|
|
529
|
+
|
|
530
|
+
目标:停止让 bridge 自己下结论。
|
|
531
|
+
|
|
532
|
+
DoD:
|
|
533
|
+
|
|
534
|
+
- [ ] `当前任务已停止。` 只在 `/stop` 确认路径出现
|
|
535
|
+
- [ ] interrupted + no reply 默认不再被翻译成“已停止”
|
|
536
|
+
- [ ] non-completed with reply 继续以 reply 为准
|
|
537
|
+
- [ ] recovery-required / final-state-unconfirmed 统一走事实型说明
|
|
538
|
+
|
|
539
|
+
### Task E:文档与维护口径更新
|
|
540
|
+
|
|
541
|
+
目标:让后续维护者不再按旧心智继续加补丁。
|
|
542
|
+
|
|
543
|
+
DoD:
|
|
544
|
+
|
|
545
|
+
- [ ] 本 spec 成为后续主参考
|
|
546
|
+
- [ ] 旧的 runtime recovery / presence spec 按新边界更新关系说明
|
|
547
|
+
- [ ] README / implementation guide / troubleshooting 中相关 shipped model 口径同步
|
|
548
|
+
|
|
549
|
+
### Task F:协议矩阵门禁重排
|
|
550
|
+
|
|
551
|
+
目标:让自动化测试直接对应协议风险面。
|
|
552
|
+
|
|
553
|
+
DoD:
|
|
554
|
+
|
|
555
|
+
- [ ] 测试地图里新增 protocol-alignment 角度说明
|
|
556
|
+
- [ ] 单元测试覆盖 start / steer / interrupt / waiting / resolved / final arbitration
|
|
557
|
+
- [ ] 集成测试覆盖文本追问、pending request、late terminal、delivery unavailable、superseded
|
|
558
|
+
- [ ] 不再新增“杂糅型大测试文件”
|
|
559
|
+
|
|
560
|
+
## 12. DoD(总完成标准)
|
|
561
|
+
|
|
562
|
+
只有当下面全部满足,这个专题才算完成。
|
|
563
|
+
|
|
564
|
+
### 12.1 行为 DoD
|
|
565
|
+
|
|
566
|
+
1. 除 slash 命令外,普通文本默认不会再被 bridge 私自吞掉
|
|
567
|
+
2. active turn 下,普通追问默认走 `turn/steer`,而不是 busy gate 拦截
|
|
568
|
+
3. waiting flag 只有在可操作实体已可见时,才真正阻塞后续输入
|
|
569
|
+
4. approval / user-input 回答能稳定清理 blocking 状态
|
|
570
|
+
5. `/stop` 之外不再轻易出现 `当前任务已停止。`
|
|
571
|
+
6. Codex 已完成但在线事件丢失时,最终结果仍能通过 pull-primary 回到用户面前
|
|
572
|
+
7. transport 生命周期不再直接成为用户看到的任务结论
|
|
573
|
+
|
|
574
|
+
### 12.2 自动化 DoD
|
|
575
|
+
|
|
576
|
+
1. 新增或重构后的 unit / integration tests 全部通过
|
|
577
|
+
2. 协议矩阵至少覆盖:
|
|
578
|
+
- start
|
|
579
|
+
- steer
|
|
580
|
+
- interrupt
|
|
581
|
+
- waiting approval
|
|
582
|
+
- waiting user input
|
|
583
|
+
- serverRequest resolved
|
|
584
|
+
- late terminal
|
|
585
|
+
- non-completed with reply
|
|
586
|
+
- interrupted without reply
|
|
587
|
+
- stale / superseded
|
|
588
|
+
3. 测试地图更新完成
|
|
589
|
+
4. 不把新增协议测试继续塞回单个巨型文件
|
|
590
|
+
|
|
591
|
+
### 12.3 文档 DoD
|
|
592
|
+
|
|
593
|
+
1. 本 spec 已可支撑低上下文工程师直接开工
|
|
594
|
+
2. 相关维护文档已对齐新 shipped model
|
|
595
|
+
3. 旧 spec 若与本 spec 冲突,已明确关系或更新
|
|
596
|
+
|
|
597
|
+
## 13. 验收标准
|
|
598
|
+
|
|
599
|
+
1. 当用户在 active turn 中发普通追问时,bridge 会优先尝试 `turn/steer`,而不是默认本地拦截
|
|
600
|
+
2. 当 runtime 进入 `waitingOnApproval` 但 approval card 尚未真正送达时,系统不会提前把这轮永久锁成 waiting_user
|
|
601
|
+
3. 当 approval / user-input 已 visible 时,用户发 `同意` / `拒绝` / 回答内容,bridge 能正确 resolve 给 runtime,并清掉 blocking 状态
|
|
602
|
+
4. 当用户发 `/stop` 后,对应 turn 才会向用户明确显示 `当前任务已停止。`
|
|
603
|
+
5. 当 turn interrupted 但并非用户 stop 且没有 reply 时,系统不会误导性地声称“任务已停止”
|
|
604
|
+
6. 当 turn 非 completed 但已有真实 reply 时,用户看到的是 reply,而不是 bridge 的本地终态文案
|
|
605
|
+
7. 当 transport 抖动但 `thread/read(includeTurns=true)` 已能确认终态时,最终结果仍会正常补回
|
|
606
|
+
8. 当上一轮结果未送达、用户又发新消息时,bridge 仍会先做 delivery ledger 对账与必要补发
|
|
607
|
+
9. README / implementation docs / test coverage map 能让后续维护者看懂当前模型
|
|
608
|
+
|
|
609
|
+
## 14. 风险、假设、待决问题
|
|
610
|
+
|
|
611
|
+
### 风险 1:`turn/steer` 在某些 waiting 状态下不接受普通文本
|
|
612
|
+
|
|
613
|
+
这是可接受风险,但必须诚实处理。
|
|
614
|
+
|
|
615
|
+
原则是:
|
|
616
|
+
|
|
617
|
+
1. 先按协议尝试正确路由
|
|
618
|
+
2. 若协议本身要求先回答 pending request,则 bridge 明确告诉用户“当前卡在这个 request 上”
|
|
619
|
+
3. 不允许 bridge 伪装成“我已经把你的追问转给 Codex 了”
|
|
620
|
+
|
|
621
|
+
### 风险 2:旧测试和旧文案会阻碍收口
|
|
622
|
+
|
|
623
|
+
这是现实风险。
|
|
624
|
+
|
|
625
|
+
处理方式:
|
|
626
|
+
|
|
627
|
+
1. 先写清协议矩阵
|
|
628
|
+
2. 再按矩阵迁移旧测试
|
|
629
|
+
3. 不兼容的旧文案直接删,不做双轨长期兼容
|
|
630
|
+
|
|
631
|
+
### 假设 1:当前 transport 先继续保留 websocket
|
|
632
|
+
|
|
633
|
+
本 spec 假设短期内不切 transport,但行为语义不能再依赖 websocket 在线性。
|
|
634
|
+
|
|
635
|
+
### 假设 2:approval / user-input 仍需要在线 request/response 承接
|
|
636
|
+
|
|
637
|
+
本期不做离线 request 重放协议,因此 blocking request 仍以内存中 pending record + 可见性账本为主。
|
|
638
|
+
|
|
639
|
+
### 待决问题
|
|
640
|
+
|
|
641
|
+
1. `turn/steer` 在 `waitingOnApproval` / `waitingOnUserInput` 下的最优退化策略,是否需要一次明确的协议级探测和错误分类
|
|
642
|
+
2. 后续是否要单独立一个 transport spec,把 websocket 实验通道替换为 stdio child-process client
|
|
643
|
+
3. `/new` 在 active turn 下最终是否保留,还是收成更强约束的显式 interrupt + new-thread 语义
|
|
644
|
+
|
|
645
|
+
## 15. 实施顺序建议
|
|
646
|
+
|
|
647
|
+
为了避免边改边乱,建议严格按下面顺序实施。
|
|
648
|
+
|
|
649
|
+
1. 先改 `runtime-client`,把 `turn/steer`、`serverRequest/resolved`、错误归一化补齐
|
|
650
|
+
2. 再改 `receiver` 输入路由主状态机
|
|
651
|
+
3. 再改 waiting visibility 和 pending request 模型
|
|
652
|
+
4. 再收终态文案与 `当前任务已停止` 语义
|
|
653
|
+
5. 最后更新测试矩阵、文档与人工验收口径
|
|
654
|
+
|
|
655
|
+
不建议反过来先改文案或先补若干 case,因为那样会继续围绕旧心智打补丁。
|
|
656
|
+
|
|
657
|
+
## 16. Ready for implementation 结论
|
|
658
|
+
|
|
659
|
+
这份 spec 当前结论是:`Ready for implementation`。
|
|
660
|
+
|
|
661
|
+
原因:
|
|
662
|
+
|
|
663
|
+
1. 问题已经不是“有没有 spec”,而是已经需要一份统一 spec 来阻止继续打补丁
|
|
664
|
+
2. 关键边界已经明确:协议事实、bridge 账本事实、用户可见语义三层分离
|
|
665
|
+
3. 子任务、DoD、验收和实施顺序都已经可直接派工
|
|
666
|
+
|
|
667
|
+
后续实现默认以本文件为主,不再依赖前序口头讨论。
|