feat(engine): withdraw_steer reports SteerWithdrawal outcome - #30
Merged
h3c-hexin merged 2 commits intoAug 27, 2026
Merged
Conversation
Hosts that re-send a queued input through another path (interrupt-and-send) must know whether the engine copy can still be committed, otherwise the same message can be delivered twice: the withdrawal used to be fire-and-forget, and "no SteerCommitted received yet" cannot be distinguished from "already committed" on the async event path. SteerControlState::withdraw now reports from the authoritative unsettled ledger, and EngineHandle::withdraw_steer returns it: - Retired: the id was pending and is now marked withdrawn — guaranteed never to be injected, settles with exactly one SteerDropped; the host may safely re-send. - NotPending: the id already settled (committed or dropped) or was never seen — no-op with no event; the host must not re-send. The withdrawal-set invariants are unchanged: unknown ids do not grow the set (bounded), settled ids stay no-ops. Behavior test steer_lifecycle_withdrawal_is_bounded_and_prevents_commit now asserts all three outcomes. No-Issue: driven by pinvou-agent#308 review (interrupt-and-send resend race); upstream-neutral, same area as the conversation-insertion primitives in Pinvou#16. Signed-off-by: luzeyang (INT) <lu.zeyang@h3c.com>
将 NotPending 明确定义为需要结合 SteerCommitted 或 SteerDropped 对账的非证明状态,并用 must_use 防止宿主静默忽略返回值。 把撤回行为测试纳入 required forkguard 过滤器,补充提交先于撤回完成时的终态事件回归。 Signed-off-by: hexin <372726039@qq.com>
h3c-hexin
force-pushed
the
feat/steer-withdraw-outcome
branch
from
August 27, 2026 04:28
fc8edb4 to
6c5fd2c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
pinvou-agent#308 的瞬发链路需要在撤回排队 steer 后决定是否经其他路径重发。原
withdraw_steer是 fire-and-forget;而SteerCommitted/SteerDropped走异步事件路径,“尚未收到事件”不能证明引擎副本仍可撤回,盲目重发可能把同一条消息投递两次。改动
SteerControlState::withdraw从权威 unsettled 账本同步判定并返回SteerWithdrawal,EngineHandle::withdraw_steer透传:Retired:id 仍 pending,已标记撤回;保证永不注入,宿主可安全经其他路径重发。NotPending:id 已不在 pending 账本中,可能已经 committed、已经 dropped,或从未见过。该结果本身不能证明消息已经投递;宿主必须结合对应的SteerCommitted/SteerDropped终态事件对账,无法确认时应保留输入并显式诊断。返回类型与方法均标记
#[must_use],避免嵌入宿主静默保留旧的 fire-and-forget 行为。未知 id 仍不写入撤回集合,保持状态有界;已结算 id 保持 no-op。两条行为测试使用
forkguard_前缀,确保 required fork CI 实际执行,并覆盖撤回先赢与提交先赢两种线性化结果。父仓适配需在更新 gitlink 后单独把 typed outcome 映射到桥接协议,并完成终态事件对账。验证
No-Issue: pinvou-agent#308 评审驱动的底座配套,与 #16 同区域,上游中性实现。