Skip to content

fix(chat): persist steering retry identity before dispatch - #6254

Merged
huangruiteng merged 3 commits into
loopx-project:mainfrom
songoow:codex/steering-retry-persistence-20261012
Oct 13, 2026
Merged

huangruiteng merged 3 commits into
loopx-project:mainfrom
songoow:codex/steering-retry-persistence-20261012

Conversation

@songoow

@songoow songoow commented Oct 11, 2026 •

Copy link
Copy Markdown
Collaborator

Current integration readback: updated onto main b760c1eb35613ac84a03cb17246eaba9030db062, head f7f02ee620bb71bf8e189d3c039f44939babb4ec. Merge conflicts resolved without dropping current-main behavior. Current targeted packaged/type/build/premerge checks and exact-head author-owned review pass. Earlier full-suite results below refer to the pre-integration head, not a new whole-suite run. Maintainer review/CI/merge remain separate.

Goal And Delivered Outcome

When browser storage refused a write, live steering still dispatched with an identity retained only in memory. Losing its response and reloading could then lose the identity needed for a safe retry. Both Adjust turn and the ordinary conversation composer now save and read back the retry envelope before dispatch. Failure preserves the editable draft and states that nothing was sent; recovery keeps the same request identity.

中文:浏览器无法保存重试标识时,两个追加指令入口都保留草稿并拒绝发送;恢复存储后沿用原请求重试。

Related to #5201; base: main. This is a bounded browser retry repair, not the full asynchronous-conversation journey.

Author Declaration

  • Written by: OpenAI Codex (GPT-6 family), model_agent.
  • Specification: the reproduced failure and required outcome above. Parent contract: docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md, durable interaction, at 3054cdcc1b236d867c0f28a454672632f27965dd.
Criterion Disposition Owner / evidence
Persist the original retry identity before live steering implemented Existing steering-recovery.ts; exact write/readback and reload regression
Refuse unavailable or silently dropped storage without losing the page draft implemented Both existing send callers; three persistence tests and packaged interaction
Preserve session, turn and same-request retry implemented Existing Chat ingress/store; real HTTP/store/subprocess regression
Keep current execution and result-adoption boundaries implemented No backend, queue, inbox or permission changes; bilingual guide preserves receipt limits

Self-check read the helper, both consumers, existing recovery scenarios and backend ingress deduplication. Future-facing pass: one shared persistence result serves both controls; no new receipt, capability, provider or configuration switch.

Scope And Continuation

The default changes only when browser retry persistence fails. A draft remains editable, but page-memory retention alone no longer permits sending. This adds no work launch or automatic retry. Existing malformed-record/server reconciliation and the parent real-model correction/adoption journey retain their separate acceptance requirements.

Frontend ordinary steward/Goal conversation controls changed. CLI, Lark and backend delivery rules are unchanged. No installed runtime was replaced; maintainer review and merge remain required.

Validation

Tested product bytes: 3d7b5193dce38769b053541f10b9f01c2bfafa1d; local focused runs preceded the DCO commit with unchanged product bytes. Input classes: synthetic/public fixtures. All 51 packaged scenarios passed on these product bytes; this PR remains draft pending exact-head review and remote checks.

Check Result / boundary
Persistence unit regressions 3 passed: exact reload identity, throwing storage, silently dropped write; baseline does not provide dispatch qualification
Packaged conversation-activity Passed: both failed-storage controls send no steering request; recovery, same identity, view/reload, interruption and terminal draft isolation
tests/test_chat_turn_steering.py 29 passed through isolated HTTP, file store and protocol subprocess; native model is synthetic
Type/build and workspace contract Passed; integrity-verified Chat bundle; existing bundle-size warning retained
Standard premerge 3 direct and 13 selected checks passed, including public-boundary scan; no skips/failures in that run
Full packaged workspace All 51 scenarios passed; the steward scenario retains its explicitly unqualified readiness/correction/recovery/return beats
Installed App / real model / full repository suites Not run for this slice; no sustained-team or deployment claim

Frontend / Visual Evidence

Actual packaged baseline and candidate with synthetic conversation data at 1512×982. Baseline accepts steering despite unavailable storage; candidate retains the inline and composer drafts and reports no send. The layout, navigation and first-screen composition are unchanged. Errors stay beside the initiating control; they are not converted into another task or a misleading success.

Before After
Baseline accepts despite storage loss Candidate keeps both drafts and refuses dispatch

Shared-authority fixture impact: N/A; no provider or authority migration. DCO and public/private boundary checks completed; generated locks and local evidence are excluded.

Signed-off-by: song <liusongstep@gmail.com>
@songoow
songoow marked this pull request as ready for review October 11, 2026 17:20

@songoow songoow 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 family; provider=OpenAI; self_reported

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

动机

普通会话中的用户在执行期间追加要求。此前浏览器保存重试信息失败后仍会发送;如果服务端收到但响应丢失,再刷新页面,就可能丢失原请求身份。本 PR 让回答内的“调整本轮”和输入框先保存并读回重试信息,失败时明确显示尚未发送并保留当前草稿。正常存储下的发送、原回合绑定和同请求重试继续保留。

这次交付限定于两个 App 入口的发送前保护,不改变 CLI/Lark、队列或收件箱规则,不证明模型已经遵循新要求。完整异步工作和独立验收仍由 #5201 跟踪。这里按 PR 中自包含的故障与不变量判断;docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md 是父级流程背景,没有将整份 RFC 当作本修复的完成范围。

改动思路

沿用原有 steering-recovery.ts:页面缓存继续保存可编辑草稿,持久化函数另外返回写入后读回是否一致。两个已有发送入口在调用执行器前检查这个结果。服务端仍拥有投递、幂等和回执,浏览器缓存不获得新的执行权限。

这一小层保护放在本地草稿与派发的交界处是合适的:只加错误提示仍会丢失恢复身份,只修一个入口会留下另一条绕行路径,新增服务器消息账本则扩大了问题。当前 PR 的边界是“两入口持久化失败时均不发送,恢复后可重试”;没有新协议或配置开关。

具体改动

  • persistRequests / retainSteeringRequest 检查精确的序列化读回,涵盖写入抛错和静默丢弃;页内草稿保留。
  • MessageActivity.steer 与工作区 sendMessage 的本轮追加分支执行相同保护,错误留在原控件附近。成功回执后的清理及确认未投递后的处理沿用原逻辑。
  • 中英文错误提示和现有用户指南公开说明新失败行为;3 个持久化回归进入既有工作区验证命令。
  • 打包场景同时检查两个入口零投递、存储恢复和草稿可编辑,并保留原有丢回执、重载、回合结束和中断竞争检查。两张截图来自实际打包的合成场景。

对主干的风险

审阅头为 3d7b5193dce38769b053541f10b9f01c2bfafa1d,基线为 3054cdcc1b236d867c0f28a454672632f27965dd。持久化数据形状、Session/Turn/请求 ID 和服务端接口未变;额外成本是一遍已有小型草稿缓存的读回。默认行为仅在无法保存重试信息时改变:此前继续发送,现在保留草稿并拒绝发送。这个限制直接保护丢回执后的恢复,不额外要求用户重复填写已知信息。

当前通过:3 个持久化用例,29 个隔离 HTTP/文件存储/协议子进程测试,51 个打包工作区场景,类型/构建/工作区契约,以及标准 premerge 的 3 个直接检查和 13 个选中检查。打包发送测试的执行器事件为合成输入;HTTP 套件使用真实本地存储和协议入口。完整 CI 的 Python、平台和发布门禁仍单独等待,不能把这些局部测试写成全仓或安装态验收。

最强反例是“浏览器调用不抛错却没有保存”:新单测要求读取同一字节串才许可发送。真实浏览器的存储抛错用例则证明发送入口没有绕过此结果。有效存储下的丢响应重试仍使用原身份,结束的回合不会把草稿转投另一回合。已损坏的旧存储记录以及完整真实模型协作,未由本切片解决或认证。

我的整体评价

批准此有界修复,没有发现需要阻止该准确提交的代码问题。它把已有恢复约束落实到了两个实际入口,改动和故障范围相称;共享持久化结果已经消除了两个入口各自判断的必要,无需额外框架。父级真实协作资格、远端 CI 和维护者合并仍是独立事项。此记录是作者账户的完整自评,不代替维护者评审或授予合并权限。

English verdict: APPROVE - 3d7b519. Both live-steering entrypoints require persistent retry readback before dispatch; focused real-boundary checks and all 51 packaged scenarios pass. Remote CI, installed-runtime and live-model qualification remain separate.

@mergify

mergify Bot commented Oct 11, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @songoow.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 11, 2026
Signed-off-by: song <liusongstep@gmail.com>
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 12, 2026

@songoow songoow 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 family; provider=OpenAI; self_reported

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

动机

普通会话中的用户在执行期间追加要求。此前浏览器保存重试信息失败后仍会发送;如果服务端收到但响应丢失,再刷新页面,就可能丢失原请求身份。本 PR 让回答内的“调整本轮”和输入框先保存并读回重试信息,失败时明确显示尚未发送并保留当前草稿。正常存储下的发送、原回合绑定和同请求重试继续保留。

这次交付限定于两个 App 入口的发送前保护,不改变 CLI/Lark、队列或收件箱规则,不证明模型已经遵循新要求。完整异步工作和独立验收仍由 #5201 跟踪。这里按 PR 中自包含的故障与不变量判断;docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md 是父级流程背景,没有将整份 RFC 当作本修复的完成范围。

改动思路

沿用原有 steering-recovery.ts:页面缓存继续保存可编辑草稿,持久化函数另外返回写入后读回是否一致。两个已有发送入口在调用执行器前检查这个结果。服务端仍拥有投递、幂等和回执,浏览器缓存不获得新的执行权限。

这一小层保护放在本地草稿与派发的交界处是合适的:只加错误提示仍会丢失恢复身份,只修一个入口会留下另一条绕行路径,新增服务器消息账本则扩大了问题。当前 PR 的边界是“两入口持久化失败时均不发送,恢复后可重试”;没有新协议或配置开关。

合入最新主线 b760c1eb35613ac84a03cb17246eaba9030db062 后复审完整差异。唯一手工冲突在 package.json,保留 steering 存储回归及主线新增的 craft browser 检查;自动合并的 composer、语言资源和指南逐项核对。浏览器已重跑两个实际入口,不把无冲突视为行为正确。

具体改动

  • persistRequests / retainSteeringRequest 检查精确的序列化读回,涵盖写入抛错和静默丢弃;页内草稿保留。
  • MessageActivity.steer 与工作区 sendMessage 的本轮追加分支执行相同保护,错误留在原控件附近。成功回执后的清理及确认未投递后的处理沿用原逻辑。
  • 中英文错误提示和现有用户指南公开说明新失败行为;3 个持久化回归进入既有工作区验证命令。
  • 打包场景同时检查两个入口零投递、存储恢复和草稿可编辑,并保留原有丢回执、重载、回合结束和中断竞争检查。两张截图来自实际打包的合成场景。

对主干的风险

审阅头为 f7f02ee620bb71bf8e189d3c039f44939babb4ec,基线为 3054cdcc1b236d867c0f28a454672632f27965dd。持久化数据形状、Session/Turn/请求 ID 和服务端接口未变;额外成本是一遍已有小型草稿缓存的读回。默认行为仅在无法保存重试信息时改变:此前继续发送,现在保留草稿并拒绝发送。这个限制直接保护丢回执后的恢复,不额外要求用户重复填写已知信息。

当前集成头复测通过:33 个隔离 HTTP/存储/协议测试、3 个持久化用例、打包 conversation-activity(两入口失败和恢复)、类型/构建/工作区契约、todo-ownership 与标准 premerge。此前旧 head 的 51 场景全量结果保留为历史证据,不宣称在新主线上重跑了全量。打包发送测试的执行器事件为合成输入;HTTP 套件使用真实本地存储和协议入口。完整 CI 的 Python、平台和发布门禁仍单独等待,不能把这些局部测试写成全仓或安装态验收。

最强反例是“浏览器调用不抛错却没有保存”:新单测要求读取同一字节串才许可发送。真实浏览器的存储抛错用例则证明发送入口没有绕过此结果。有效存储下的丢响应重试仍使用原身份,结束的回合不会把草稿转投另一回合。已损坏的旧存储记录以及完整真实模型协作,未由本切片解决或认证。

我的整体评价

批准此有界修复,没有发现需要阻止该准确提交的代码问题。它把已有恢复约束落实到了两个实际入口,改动和故障范围相称;共享持久化结果已经消除了两个入口各自判断的必要,无需额外框架。父级真实协作资格、远端 CI 和维护者合并仍是独立事项。此记录是作者账户的完整自评,不代替维护者评审或授予合并权限。

English verdict: APPROVE - f7f02ee. Both live-steering entrypoints require persistent retry readback before dispatch; current integration checks and packaged conversation-activity pass; the earlier 51-scenario run is historical evidence only. Remote CI, installed-runtime and live-model qualification remain separate.

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

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.1-sol; OpenAI; runtime_reported; xhigh.

REQUEST_CHANGES — f7f02ee 仍有一项 P2:当前请求身份已经持久化,也会因另一个未保存草稿导致整个缓存无法重写而被阻断。

动机

正在对话中追加指令的用户需要在响应丢失或刷新后继续同一请求。 以前保存失败仍可发出调整,丢失响应后可能无法恢复原身份;现在新身份未保存时会保留草稿并拒绝发送,但一个未保存草稿也会拖住另一个身份已保存的请求。 新请求的失败提示和同身份恢复已实测;已保存请求被无关缓存写入失败阻断的问题仍在。 本批不授予执行权限、不改变后端确认语义,也不证明真实模型已采用指令或完成整个对话 RFC。

改动思路

复用同一恢复 helper 是合理的,但整个缓存能否重写不能代替当前请求身份是否已持久。 在现有两个调整入口完成当前请求持久身份核验和同身份恢复,不增加全局门禁或新配置。 改动的安全意图有正向价值,但必须同时检验“无身份却发送”和“已有身份却无法继续”两个方向。

参考 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,冻结 revision 3054cdc,并结合 #5201 已接受的本批恢复边界逐项核验:Waiting-Identity 要求原 Session/Turn/text/ingress ID 留存并同身份重试;Waiting-Scoped-Composer 要求按 Goal/Agent 对话维护草稿,一个对话的等待不能锁住另一个对话;Waiting-No-Auto-Send 保留刷新仅恢复草稿;Parent-Live-Adoption 属于完整 parent 的独立后续验收,本批不宣称完成。

具体改动

  • steering-recovery.ts 将保存改为返回 boolean,retainSteeringRequest 写缓存后检查整个 serialized JSON 的存储读回;字段和存储格式保留原样。
  • MessageActivity.steer 与 PersonalWorkspacePage.sendMessage 两个入口在返回 false 时停在前端并保留草稿,英中错误文案及使用指南同步说明默认行为变化。
  • 新单元测试覆盖抛异常、静默丢写和恢复;原生 conversation-activity 浏览器测试覆盖两个入口无请求。两个文档 PNG 是公开合成展示,另外实际走过当前打包页面及原生 HTTP/文件 Session store。

[P2] 当前请求的持久事实不应被整个缓存写入状态替代 — apps/presentation/dashboard/src/features/personal-workspace/steering-recovery.ts:33-39。在存储正常时保存 A 的原身份;将容量限制为现有长度,另一 Goal/Agent 的 B 新草稿写入失败,B 仍留在共享 Map;重试 A 会再次序列化 A+B 并抛 QuotaExceededError,返回 false,两个调用者因此拒绝 dispatch。读回证明 A 的 sessionId/turnId/text/id 仍完整、相同。实际打包 UI 上,inline A 已保存、composer B 未保存的对应情形也产生两个错误且零 steering POST;恢复写入后,A 使用同一个 client_ingress_id 成功通过原生后端。问题不是缺少 A 的安全前提。

最小修复:读取并核验当前请求 key/sessionId/turnId/text/id 的已持久记录;该记录完全匹配时允许原身份重试,其他未持久草稿不能阻断它;新身份、读失败或字段不匹配仍须先成功保存。 回归测试需覆盖跨 Goal/Agent 以及 inline/composer 的已有 A + 未持久 B;同时保留新身份未写入、静默丢写、读失败、字段不匹配的拒绝路径,不能用 page Map 代替持久证据。

对主干的风险

独立执行恢复 helper 的 3 个单元测试、真实原生 steering/ingress/store 33 个测试、Workspace contract、打包 build 和 source verify 均通过。当前打包 UI 实际验证抛异常/静默丢写时零 dispatch、恢复后原 ID 发送、重载历史和 390px 窄屏。冻结 base b760c1e 也实测:输入时已保存的原身份在发送时写入失败后仍可安全发送;不能把这个 base 观察误称“丢失身份”。另有实际 TS owner 的跨对话配额反例和 20 个 authority 派生上下文的合成 cache 测试;这些不是 20 个领域 agent 的自然运行或付费模型采用证明。

故风险来自共享 Map 的不同主体被一个写入门禁绑在一起,缓存积累时可能使长程继续工作需要不必要干预。新增显示有恢复指引,但刷新可能丢掉 B;已经安全的 A 不应为 B 付出这个代价。后端 wire/接收确认语义未改变,没有新 capability 或权限。UI/HTTP/store 为真实生产入口,模型子进程为仓库合成 protocol peer;没有真实模型、安装态 App/Lark 或长期净收益测试。测试过程中的 fixture 空闲超时与命令路径纠正保留为 harness 记录,不归因成 PR 缺陷。

我的整体评价

复用同一恢复 helper 是合理的,但整个缓存能否重写不能代替当前请求身份是否已持久。 在现有两个调整入口完成当前请求持久身份核验和同身份恢复,不增加全局门禁或新配置。 当前暂缓:改善无持久身份的安全性是真的,已持久请求被无关草稿阻断也是真的。在原 helper 内按当前记录核验即可修正,不需新全局配置、另一份 authority 或宽泛重构。完成上述反例修复和相反方向的拒绝测试后再评审;此处未改作者分支、合并或升级本机。

English verdict: REQUEST_CHANGES — f7f02ee; P2: an already-durable request is blocked by an unrelated unpersisted shared-cache entry. Reproduced through the actual TS owner and packaged UI/native backend; 3 unit and 33 native tests pass but miss this counterexample. Qualify the current persisted request without weakening new-identity refusal.

Integrate current main and allow an exact durable retry identity to proceed when an unrelated draft cannot be persisted. Preserve unsaved drafts and fail closed on mismatched identity or unavailable storage.

Signed-off-by: song <liusongstep@gmail.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

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 family · OpenAI · self_reported

Reviewed exact head: 2d406bc。本次全量 base-to-head(60d833b13c85135587b725013b247e827663ffb9)评审,另外核对上一评审到本 head 的改动;不继承作者或旧 head 的 verdict。

动机

正在会话中追加指令的用户需要在响应丢失或刷新后继续同一请求。
此前新身份保存失败仍会发送,上一修订又会因无关草稿写入失败而阻断已保存请求;现在新身份未保存时保留草稿,已有完全匹配的持久身份可以独立重试。
两个当前打包入口完成未保存身份零发送、已保存 A 与未保存 B 的独立重试,B 草稿仍可编辑;原身份重载与后端幂等由独立生产 HTTP/store/protocol 测试验证。
不改变后端接受确认、执行权限、CLI/Lark 或队列;不证明真实模型采用指令、安装态 App 或整个协作 RFC 完成。
父级真实模型采用、安装态 App/Lark 和多轮团队独立验收仍开放,本切片不等同这些完成。

改动思路

两个发送入口共享原恢复 helper;精确读取当前持久记录解决过度阻断,不增加全局开关、另一套 store 或接收权威。
本 PR 同时完成两个前端入口的发送前身份保护和恢复,后端仍拥有接收、幂等与结果;无需把 parent 全部完成作为本修复前置条件。
相比不改、现有 owner 小修和新增框架,当前机制的职责边界合适;功能可达不能替代后续有用工作或原 owner 前置条件。记忆中的产品旅程建议在此采用,但 context delivery 不等于收益证据。

具体改动

全量 10 个文件,+117/-13。现有恢复 helper 返回持久核验结果,inline/composer 两个入口在 dispatch 前使用它;中英文错误、用户指南、package smoke 入口、四项 owner 单测和原 conversation-activity 场景同步更新;两张 PNG 为公开合成展示。未增加后台轮询、schema 或权限。

  • apps/presentation/dashboard/src/features/personal-workspace/steering-recovery.ts:53 / retainSteeringRequest:Qualify current persistent request。
  • apps/presentation/dashboard/src/features/personal-workspace/message-activity.tsx:66 / steer:Inline guard before dispatch。
  • apps/presentation/dashboard/src/features/personal-workspace/personal-workspace-page.tsx:1853 / sendMessage:Composer guard before dispatch。

规范依据 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,spec_revision 60d833b,以修改前 accepted 文本及现有 PR 接单边界判断。规范行没有额外编号时保留原行名:

  • Acceptance:Lost response preserves scoped original identity and one logical request. — implemented
  • Scope:A→B→A and late events retain original source/Session/Turn; waiting in one composer cannot lock another. — implemented
  • Correction/stop:Actual receiver adoption remains distinct from transport acceptance. — deferred
  • Packaging:Supported local installed bundle completes first request and return. — deferred

对主干的风险

独立当前验证:4 steering owner 单测、20 独立 scope 正反探针、52 production HTTP/store/protocol 测试、packaged conversation-activity、build/verify --source、3 direct + 13 selected premerge,相应 qualifying run 无 product failure/skip。原生产 HTTP/Session store 和 protocol subprocess 独立运行;浏览器发送路由为 synthetic fixture,因此它证明当前 compiled 控件接线和原 id,而不是付费模型/真实远端执行器。旧失败被相同输入区分后,反方向新请求、静默丢写、读失败和 scope/字段变化均仍拒绝。

4/10 变更路径与上次 blob 相同,当前 helper/两入口/文案与测试重新检查;main 整合另外归因。20 scope 为隔离存储场景,未执行二十个领域 agent 的真实业务。

初次测试路径错误未执行 oracle,纠正为仓库现有文件;并行 browser 的默认端口冲突后单独重跑成功;旧 head 上命令 verify-source 无效,按其文档使用 verify --source 通过。这些 harness 错误保留,不归因成 PR regression,也未放宽断言。CI 为 not_consulted,未查询/等待。不改变后端接受确认、执行权限、CLI/Lark 或队列;不证明真实模型采用指令、安装态 App 或整个协作 RFC 完成。

当前没有阻塞发现。上一评审的 A 已持久 / B 未保存反例在旧 f7f02ee 返回 false,本 head 的独立相同输入返回 true;20 个隔离 scope 都通过,四字段改变、换 key、读失败仍拒绝。原生 packaged 场景验证两入口,新身份无发送、A 用原 id 发送、B 草稿保留,未用页面 Map 冒充持久证据。

我的整体评价

两个发送入口共享原恢复 helper;精确读取当前持久记录解决过度阻断,不增加全局开关、另一套 store 或接收权威。
本 PR 同时完成两个前端入口的发送前身份保护和恢复,后端仍拥有接收、幂等与结果;无需把 parent 全部完成作为本修复前置条件。
长程效果方向为正:已有身份不再受无关草稿拖累,原请求恢复保留幂等边界。效率改善体现在减少无必要恢复存储/重填的人工干预;额外持久读有小型 cache 成本,没有真实模型/多日净收益数字。当前批准这一有界修复,parent journey 保留独立验收。
相邻有界 refactor 已应用在现 owner;未发现需要添加另一层框架的理由。未修改作者分支、dismiss review、merge 或升级本机。

English verdict: APPROVE - 2d406bc. The previously reproduced durable-A/unsaved-B overblocking is repaired through the existing owner. Four unit, 20 isolated scope, 52 native HTTP/store/protocol checks and the current packaged controls pass; new or mismatched identities still refuse. Live-model, installed-App and parent-team acceptance remain separate.

Reviewer execution observation is currently unavailable (turn_identity_unavailable); family attribution is self-reported and does not certify a backend build.

@huangruiteng
huangruiteng merged commit 255a250 into loopx-project:main Oct 13, 2026
31 of 36 checks passed
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.

3 participants