Skip to content

feat(lark): keep App input feedback independent of answer delivery - #7858

Merged
loopx-agent merged 4 commits into
mainfrom
codex/attached-chat-current-20261101-2307
Nov 2, 2026
Merged

loopx-agent merged 4 commits into
mainfrom
codex/attached-chat-current-20261101-2307

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

App 发出的原会话消息已经镜像到 Lark 时,现在复用现有表情回执:Get 表示已收到,只有 Core 已开始处理才显示 OnIt,终态清理处理中状态。每次表情操作重查原授权、canonical 输入和已核验的实际镜像;长输入使用最后一条实际分段消息,关闭表情反馈时正文路径保持。

修复原评审指出的阻塞:表情 IO 独立于正文 outbox 锁,最多使用原回复池的一个槽位,回写只合并反馈字段,允许同一会话当前及后续答案继续送达。复用原 reaction journal,未知 provider 写入不重发,不创建新入站消费者或业务执行。

验证:439 项投递、表情和监听完整测试通过;最终 36 项 App 旅程和 5 项并发/关闭/失败检查通过。相同真实 HTTP/Core/原服务回复池 fixture 在原实现中复现“表情卡住阻塞答案”,修复后当前与后续答案均先于表情释放送达,6 条正文回执在并发合并后保留。完整 premerge、语法、双语 RFC、边界检查通过。合成 provider 资格不代表已完成真实 Lark App 表情与安装后可见性验收,部署后沿原服务另行核验。

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=max

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

[P2] 可选表情 IO 在正文 outbox 锁内阻塞已完成答案。 这是独立本地反例确认的新增问题,不是 CI 未知导致拒绝批准。

动机 / Motivation

在 App 输入后、仍从原 Lark 私聊接收回传的用户,以及同一 Session 的现有投递 worker。例如 App 的用户输入镜像已送达,Core 也已完成答案,但新 Get 表情的 provider 请求尚未返回。当前 head 在正文 outbox 的锁内等表情 IO,后续答案因此不能继续;用户只看到输入镜像,却要等非必要反馈恢复后才能收到已经完成的结果。目标应是只给已核验的用户镜像显示 Get/OnIt,并让 queued、running、terminal 反馈准确;反馈失败或 pending 时,原正文仍能独立继续,且不重复写入、启动执行或结算原请求。本切片不完成安装版或全跨端同步验收,不新增 executor、capability 或权限;实际 Lark 呈现、完整 provider 延迟和长期净益仍需独立证据。

改动思路 / Approach

复用现有 Lark reaction journal、每消息锁和 canonical source/Turn 核验是合适的;但可选反馈 provider IO 必须退出正文投递持锁的关键路径,不能让 observer 的等待挡住已完成的必要结果。当前范围为六个文件 +549/-21:两个现有 Lark provider owner、343行测试扩展和28行成对 RFC 说明;不需要新增通用队列或 executor,所需修复应局限于现有正文/反馈执行边界。

现有 implementation 对来源、Turn、冻结正文和 provider post 的核验较完整;Get 保留、OnIt 仅在 starting/running、terminal 清理和 unknown-write journal 也有实际测试。问题不在是否复用 journal,而在新反馈被同步嵌入必要正文的持锁路径,普通立即失败 fixture 捕捉不到 provider 尚未返回的情况。将可选表情 IO 从正文 outbox 持锁路径分离,保留每次 effect 前的来源/Turn 检查、原 journals 和未知写入不重试;用 held-reaction 反例证明原答案可在表情恢复前送达。

具体改动 / Changes

精确 head 5b089800b421d1ac9a0aac5d5ba807ef026c7f8c,不可变 base 111519af76e56141c56eb7a27443da59def775b9;审查覆盖完整 diff,而非只核对上次发现或作者测试统计。

关键代码讲解

  1. _web_projection_paths 增加 Turn-directory 变化和失败反馈发现;mtime 是 discovery hint,不能代替发送授权。关闭反馈仍沿原正文发现路径。
  2. _web_projection_feedback 只处理已 verified 的 user mirror,逐次重查 canonical input、原 Session/Turn、绑定/授权和冻结 provider 消息;长输入选择最后一条实际 post,不对 parts locator 操作。
  3. _reconcile_outbound_input_reactions 复用创建/清理 journal,outbound 明确 captured_pending=False,没有伪造 incoming event 或结算原请求。已收到成功而处理中失败的已知写入计数保留,旧 API 参数默认值也保持。
  4. _reconcile_web_projection 从进入到返回都持有 outbox fence;1515行 新增的直接反馈调用在选取下一个 canonical body 之前同步等待,形成阻塞点。

已在 diff 前读基线原会话规格,并核对新增双语条款:original Session and source isolation → implemented;once-only feedback recovery → implemented for inspected source cases;nonblocking optional feedback → not_met;installed presentation → deferred,实际 Lark 呈现与安装验收仍未证明。既有 Core status、receipt、原 source/audience 词汇沿用;private feedback 意图由新镜像 write 前自动产生,状态投影不能成为新 grant。

对主干的风险 / Risks

[P2] 将可选反馈移出正文持锁路径。 触发条件是 Core 已完成原答案、正文 API 可用,但表情 create 请求 pending。独立反例只用 Event 挂起这一个 provider 操作,保留原10秒 drain约束:

相同原会话/已完成 Core 表情释放前的答案 结果
不可变基线,反馈开 已继续 PASS
当前 head,反馈关 已继续 PASS
当前 head,反馈开 仅一条用户镜像,答案未继续 FAIL;释放表情后才到达

这是实际 Core/HTTP/store/provider adapter 路径,不是复制新 helper 的期望。_reply_runner 的单次 provider bound 为30秒;即使最终会 timeout,也已经把非必要反馈等待接到了后续必要结果上。将可选表情 IO 从正文 outbox 持锁路径分离,保留每次 effect 前的来源/Turn 检查、原 journals 和未知写入不重试;用 held-reaction 反例证明原答案可在表情恢复前送达。

四个完整 Python 模块:base434 PASS/0 FAIL;head452 PASS/1 FAIL,19个新增用例全部通过。唯一共同用例变化是长回复在原10秒 drain约束超时;单例后来 base/head 都通过,故首次超时的完整原因仍未知,不能因重跑绿就抹去,也不声称上述 controlled probe 已解释它的全部成因。该 probe 独立、稳定地暴露新的同步阻塞路径。

撤权、provider身份/正文/Session/Turn改变、context recovery、unknown-write 不重试、长输入最后 post、历史已结束镜像不回填,以及反馈关闭/立即失败的正文路径均有 PASS 证据。focused Ruff、配置17模块 mypy、双语/public scan和6 direct+11 selected premerge命令 PASS;整体仍 FAILexit1 quality_stale_receipt。初次测试路径拼错、no tests collected 的失败保留,修正实际路径后才执行上述完整模块。CI 未查询或等待。

我的整体评价 / Verdict

REQUEST_CHANGES:有用的反馈路径、权限核验和 journal 复用已实现,但必要结果仍依赖可选 provider 返回,当前有反例,不能宣布这个用户任务完成。long_horizon=regression、user_experience=regression 的依据是原答案被拖住,而非 CI 未知;关闭路径和原来源保护不能抵消开启后的阻塞。修复应保留有用实现和原证据,在现有 owner 内消除耦合,再运行同一 held-reaction、关闭/撤权/未知写入与正文重放反例,不需要新 executor、通用队列或更宽权限。

真实 Core/HTTP 与 synthetic provider 已核验状态和目标消息;本轮没有实际 Lark 原生呈现截图或安装读回,不能把 API 回执与字段正确等同可见反馈已验收。安装版、实际 Lark 呈现与 provider 延迟未验证;完整 Python 仓库矩阵、真实 PostgreSQL 和长期采用/成本净益未获本轮资格。最初长回复超时的完整成因仍未知,后续单例通过没有抹去失败。

English verdict: REQUEST_CHANGES 5b08980; optional reaction IO waits under the required body outbox fence and blocks already-completed answers. Base/on and head/off advance; head/on advances only after reaction release. This is an independently reproduced regression, not a CI-success requirement.

…urrent-20261101-2307

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
@loopx-agent loopx-agent changed the title fix(lark): track feedback on verified App input mirrors feat(lark): keep App input feedback independent of answer delivery Nov 2, 2026
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer: model_agent | GPT-6 | OpenAI | self_reported (host execution observation unavailable)

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

动机 / Motivation

在 App 输入后,从原 Lark 私聊接收答案的用户和同一 Session 的投递 worker。 App 输入已镜像到原 Lark 私聊且 Core 已完成答案时,修复前挂起的 Get 表情请求阻塞正文;修复后当前和后续答案在表情释放前继续送达。 仅已核验用户镜像得到 Get/OnIt;必要正文与可选表情分别推进,保留原来源和未知写入保护。 本 PR 不创建新消费者、业务执行器或通用队列,不补写历史已结束镜像的表情。 真实安装后的 Lark 呈现、实际 App 表情往返和长期延迟仍需沿原服务验收;合成 provider 证据不代表这些已完成。

改动思路 / Approach

正文回执、canonical Turn 和 reaction journal 各有既有 owner;可选反馈可以观察和投影状态,不能持有必要正文的投递锁。 原功能的 Get/OnIt 状态与目标核验保留;本轮删除正文扫描对反馈重试和 Turn 目录 mtime 的耦合,改由原四槽回复池最多一个独立反馈任务观察 canonical Turn。反馈只短暂读取 outbox,在另一把反馈锁内等待 provider,最后重新取得正文锁并只合并仍匹配冻结正文的反馈字段。正文 worker 因而可以发送当前和后来加入的答案。在原 Lark provider 和四槽回复池内分离反馈 IO,沿原授权和 journals 执行,不新增执行或授权 authority。 表情状态是观察投影,原生 Turn 和来源授权仍是 authority。

具体改动 / Changes

本轮以原评审 5731202458 的不可变验收框架(spec_revision 5731202458)为修复规范,结合已读基线 111519af76e56141c56eb7a27443da59def775b9 的原会话 RFC;没有用本 PR 新写的条款反向定义要求。C-SOURCE(原 Session/来源隔离)、C-ONCE(一次性反馈恢复)、C-IO(可选反馈不阻塞)均 implemented;C-INSTALLED(真实安装呈现)deferred,由同一受托部署验收继续,未声称已取得真实截图。完整 PR 为七个现有文件 +641/-22,其中397行测试、33行成对 RFC、211行生产新增;对比旧评审的改动与整个 PR 分别核对。

关键代码讲解

_reconcile_outbound_input_reactions 复用原每消息锁、创建和清理 journal,outbound 明确 captured_pending=False,原 incoming 默认值保持 True;既不制造入站消息,也不结算原请求。未知写入仍停留在原 prepared 记录,不重发。

_web_projection_feedback 只处理已核验 user mirror;每次 effect 前核验原来源、授权、canonical 输入/Turn 和冻结 provider 内容。queued 只收到,starting/running 才处理中,三类终态清理;长输入使用最后一条实际分段 post。

_reconcile_web_projection 的正文锁内不再执行表情 IO。reconcile_app_feedback 在锁外执行可选反馈,仅在来源与冻结 phase 仍一致时合并 feedback,保留并发新增正文和 outbox 状态,无变化反馈不重复写回。_reconcile_private 复用同一有界池,最多一个反馈 Future,没有新 executor、队列或消费者。

对主干的风险 / Risks

原 P2 的最强反例保留:只挂起一个 Get create,Core、HTTP、原协议进程、文件存储及真实服务回复池继续运行。基线在等待期限内只有输入镜像,FAIL;最终提交当前和后续六条 canonical 正文在表情释放前送达、合并后六条 verified 回执均保留,PASS。该验证也排除了“只挪锁但仍卡住同一路径 Future”的较小伪修复。来源/App/Session/Turn/正文变化、撤权、context recovery、assistant、历史不回填、长输入和未知写入仍有负例覆盖。

完整相关 owner suite439项 PASS;最终无变化回写优化后的36项 App 旅程与5项并发/失败检查 PASS。Ruff、配置 mypy、双语 RFC、完整 premerge 和公开边界检查按最终提交核验。初始测试文件路径错误保留,修正路径后才取得完整结果。首次整组还出现一次8秒启动前置等待超时,此时挂起表情的断言尚未开始;没有为首次扫描设8秒产品承诺,故单独把该前置等待改为20秒,挂起后的正文仍按既有10秒 drain 约束验收。相同新版 fixture 在原实现仍失败、最终提交通过;首次调度延迟的具体性能成因未归因。旧评审的长回复十秒超时成因仍未知,后续单例和当前 suite 通过不抹去历史,也不冒称 held-reaction 解释了所有原因;旧 quality_stale_receipt 失败继续保留,当前 Goal 的资格策略已关闭,当前 premerge 是独立结果。按 wait_for_ci=false 未查询、轮询或等待 CI。

语义与 CI 对齐

复用已有 canonical status、reaction journal、source grant 和 body outbox 词汇;Lark 细节保留在 provider 层。反馈意图由当前原镜像写入路径自动产生,其结果只是投影,不是新的授权或业务义务。回滚保留原 journals,可用既有关闭表情选项恢复原正文路径。

我的整体评价 / Verdict

APPROVE,justified_increment;long_horizon 和 user_experience 均 improved:独立 held-provider 反例证明必要结果持续推进,而不是仅记录一个阻塞状态。旧 P2 已在现有 owner 内修复,新增一个服务边界比新建异步 executor 或通用队列更合适;原来重复的发现状态也已删除。未改变前端或 Lark 渲染器与布局,新来源复用既有表情;真实 provider 呈现仍是部署验收缺口。真实安装后的 Lark 呈现、实际 App 表情往返和长期延迟仍需沿原服务验收;合成 provider 证据不代表这些已完成。 源码批准不代表所有积压业务或安装验收完成。

English verdict: APPROVE — optional App feedback is isolated from current and later canonical answer delivery, with original source and unknown-write fences retained.

@loopx-agent
loopx-agent merged commit acc6590 into main Nov 2, 2026
5 of 6 checks passed
@loopx-agent
loopx-agent deleted the codex/attached-chat-current-20261101-2307 branch November 2, 2026 16:55
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.

1 participant