fix: conductor 双态窗口收敛——标签触发转移可达(ADR-0085) - #353
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 10 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughConductor 工作流更新状态标签解析逻辑。 Changes状态标签转移
Suggested labels: Merge Risk: ⚪ Minimal · up to This localized workflow change is merge-ready after normal checks and review; no actionable merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
PR Summary by QodoFix Conductor dual-state label window so label-triggered transitions remain reachable
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo
1. Dual-state invalid jump no-op
|
| ev_label_name = ev[len("label:"):] if ev.startswith("label:") else "" | ||
| others = [s for s in states if f"state:{s}" != ev_label_name] | ||
| if ev.startswith("label:state:") and len(others) == 1: | ||
| current = others[0] |
There was a problem hiding this comment.
2. Dual-state invalid jump no-op 🐞 Bug ≡ Correctness
当同时存在两个 state 标签且事件为 label:state:* 时,代码会把 current 收敛为“另一态”并继续;若该组合在 transitions.yaml 中没有匹配转移,则会走到“无匹配转移→noop”分支退出 0,导致双 state 继续并存且不会 fail-closed。该行为回退了原先“多 state 直接 abort”的一致性保护,错误贴标/跳态会被静默吞掉并污染状态机。
Agent Prompt
### Issue description
当前对 `len(states) > 1` 的“收敛”策略只检查事件是否为 `label:state:*` 且双态窗口中“另一态”数量为 1,就会将 `current` 设为该“另一态”。但如果该 `(from_state=current, event=ev)` 在 `governance/transitions.yaml` 里不存在,后续会走到“无匹配转移→noop→exit 0”,从而让 issue 继续保持双 state 并存,且不会 fail-closed。
这会把原本的“多 state = abort(保护一致性)”弱化为“多 state 也可能静默 noop”,让错误贴标/跳态更难被发现和修复。
### Issue Context
- `issues.labeled` 事件只会给出“新增的 label”,无法保证旧 state label 已被移除。
- 本 PR 的目标是让合法转移在双态窗口可达,但仍应对“无合法转移的双态”保持 fail-closed(或至少回滚事件标签后再退出)。
### Fix Focus Areas
- .github/workflows/conductor.yml[208-241]
- .github/workflows/conductor.yml[233-241]
- governance/transitions.yaml[91-116]
### Suggested fix approach
1. 在双态收敛分支中引入“收敛模式”标记(例如 `dual_state_window = True`),并保留 `event_state`(从 `ev` 提取的 state 名)。
2. 在加载 `transitions.yaml` 并执行转移匹配后:
- 若 `dual_state_window` 为真且 `t is None`(没有匹配转移),则应 **fail-closed**(`verdict=abort` 并退出非 0),避免把双态不一致静默吞掉。
- 可选(更强一致性):在 abort 前尝试回滚本次事件新增的 state 标签(DELETE `state:<event_state>`),使 issue 回到单态旧状态;回滚失败则仍应 abort。
3. 保持本 PR 既有的“合法双态窗口可达”逻辑不变:当存在匹配转移时正常执行 `swap_state`,最终写出单态。
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Card: #350
T8 首次实走(#349 置 state:done)实测暴露:actor 置新态时旧态并存,labeled 事件携带 [in-progress,done] 双态,conductor 多状态守卫先于转移匹配 abort——标签触发的转移全族(T5/T7/T8/T9)在该写序下不可达。收敛:事件标签=新态、另一态=转移前态;swap_state 移旧置新后终态单态。守卫对非 label:state: 事件与真并存维持 abort。AST+YAML 双验证通过。
Summary by CodeRabbit