Skip to content

feat(dashboard): explain Goal lifecycle action review decisions - #4249

Merged
huangruiteng merged 10 commits into
loopx-project:mainfrom
songoow:codex/action-review-plan
Sep 12, 2026
Merged

huangruiteng merged 10 commits into
loopx-project:mainfrom
songoow:codex/action-review-plan

Conversation

@songoow

@songoow songoow commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Behavior

Goal lifecycle actions use a TypeScript review plan to explain direct execution, review, gates, stale previews and verified outcomes. Valid ready stop retains the direct path; resume/delete require review. Protected, unknown, incomplete or mismatched previews cannot execute directly. Apply readback must match the requested proposal, Goal and operation; typed backend codes identify stale state.

The existing Chat transport now validates each evidence element as nonblank text without changing its contents. The compiler reuses that schema, so nulls, objects, blank strings and mixed arrays cannot qualify a direct action. Generic empty evidence arrays and deferred retry behavior remain compatible.

Validation

  • Malformed evidence, compiler-bypass, permission/state/identity and generic parity cases; existing CommonJS consumers.
  • 38 proposals produced through the real local HTTP action service, covering all 11 action kinds, passed the transport and compiler; valid stop remained direct.
  • TypeScript/Chat build and complete development/packaged workspace browser scenarios, including desktop/mobile API parsing, visible errors, rollback and zero apply calls for malformed evidence.
  • Frozen-head standard canary: 15 selected checks, zero failures.

Scope and integration

Head 93ad4f4b7d4fe480e6505b6b70b5807e1a892075 includes main 84334f794. All original action regressions moved into the current typed-actions scenario and fixture; navigation and recovery scenarios remain intact.

Dashboard and packaged Chat/Desktop consume the plan. There are no new settings, CLI/Lark contracts or backend authority rules. #4132 retains legal-action authority; attention delivery and #4172 material receipts are outside this slice. The future-facing pass centralizes the evidence rule in its existing transport owner instead of adding another validator or state machine.

Hosted CI and maintainer review must qualify this head. Browser negative cases use controlled API fixtures; valid producer behavior was checked separately through the real service.

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

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

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

@songoow songoow left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

English verdict: REQUEST_CHANGES for reviewed head b9088302cf7f7177e3d9ddef3e91a095252a3038. The previous-head checks failure was a duplicate-match browser selector, reproduced in Chromium and fixed without changing product code. New exact-head CI is pending. The immutable baseline and product-identical preceding head passed the same original 24-criterion browser harness with identical complete semantic reports; final-head development and packaged suites also passed after the selector fix. This is an author-owned review, not independent approval.

Reviewed head: b9088302cf7f7177e3d9ddef3e91a095252a3038
Base: 6c0a43c34。作者自审;本条不是独立 reviewer 的批准。

动机

这个 PR 要解决的是 Goal 生命周期操作的展示判断分散,以及状态反馈容易混淆“服务返回了结果”和“已经验证操作完成”。原来暂停入口只看预览是否 ready 就直接执行;恢复和删除走抽屉确认。正常路径简洁,但保护条件、过期信息、读回失败和请求目标匹配缺乏同一处解释。

最强的反对理由是:只有暂停需要直接执行,为它引入一个通用框架可能得不偿失。因此这里保留了已有 Chat proposal、preview/apply、指纹和服务端规则,只增加很小的内部编译器与纯类型定义,并由已有 Goal 入口及动作抽屉实际消费。它不是新的权限系统,也不扩展到 DSH、Lark 或新的合法动作目录。代码的价值在于减少误判与重复判断,不是减少所有确认步骤。

改动思路

输入仍然是 Chat transport 已解析的 TypedActionProposal。编译器从其状态、权限分类、验证信息、目标与 receipt 派生 direct、review、gated、refresh、repair 等展示结果。Goal 列表使用 direct 结果决定是否继续调用既有 apply;抽屉使用同一计划说明原因、控制确认入口。完成判断要求匹配请求身份且读回已经验证。

本次重新对完整 base-to-head 进行检查,并整合了最新主干的 #4250 浏览器恢复 fixture。此前 #4243 的决策范围、#4244 的 capability context、#4246 的富文本修复及其浏览器断言均保留。仍开放的 #4132 负责合法 Goal 动作目录,本 PR 不复制它的计算;这里解释已经存在的 proposal。

复查发现,直接把 gate 对象作为所有动作的当前阻塞事实会破坏旧路径:真实 ChatActionStore 从 gated 转成 deferred 时保留历史 gate,旧 UI 允许稍后再试。当前修复只对 Goal lifecycle 使用保守的原始 gate/stale 优先级,其他动作继续根据既有状态重试。临时隔离 store 的真实转移结果输入修复前、后的编译器,分别得到 canApply=false 和 true,证明不是为了测试伪造 producer。

具体改动

关键代码讲解

  1. compileActionReviewPlan:内部展示编译器。只有已知、完整、ready 的暂停可以 direct;恢复和删除仍需审阅。unknown、incomplete、stale 不因按钮文字获得执行资格。generic deferred 的历史 gate 不再被误认为新的阻塞。该函数没有写入、列表扫描或调度副作用。
  2. requestGoalLifecycle:在 preview 返回后检查 Goal 和 operation 是否与用户请求一致,再决定是否自动 apply。移动端进入生命周期操作时关闭导航,避免审阅抽屉被导航遮住。
  3. applyProposal:补齐 apply 响应的 proposal ID、action kind、Goal 和 operation 检查。即使响应声称 projection_verified=true,身份不匹配也不能确认完成;无验证读回同样显示结果未确认,并回滚乐观展示。回滚只针对前端显示,不声称撤回已经发生的服务端效果。
  4. isStaleActionFailure:消费服务已有的 action_stale/action_conflict 错误码和 proposal.status,取代按翻译后的错误文案匹配 stale/conflict。测试覆盖“外部错误文字含 conflict,但并非来源过期”的反例。

纯展示类型位于不依赖浏览器运行时的文件中。此前 WorkspaceModel 间接导入 Chat 的 import.meta,导致 CommonJS consumers 无法编译;该问题已通过实际 usage-progress 失败复现并修复。英中 RFC 均说明内部类型、当前入口、保留的后端权威和行为变化。生成的 Chat bundle 与当前源码一起更新,不包含本地测试状态。

对主干的风险

主要风险是误关闭既有重试路径,或者在错误目标的 receipt 上报告成功。前者已通过真实 store 转移及各 generic action 的配对断言覆盖;后者通过实际 Goal 按钮进入 preview/apply 的浏览器测试,注入错 proposal、错 Goal、错 operation、stale 409 和未验证读回进行检查。服务响应由测试控制,因此这些浏览器案例证明消费者如何处理异常,不证明后端实际生成这种错误;真实 HTTP Chat action smoke 与 Goal 激活/CORS 测试用于分别验证服务边界。

新增展示不会关闭 gate、消费 quota 或授予许可。远端 SSH 生命周期继续使用自己的绑定和读回契约;只读来源仍无写入入口。本 PR 没有新的可选开关,也没有把 capability 存在当作激活证明。删除和恢复仍然需要审阅。

最终本地验证已完成:编译器与 CommonJS 检查、TypeScript/Chat 打包、完整开发浏览器、完整打包浏览器均通过;canary 选中 12 项、失败 0 项;Goal 激活/CORS 的 32 个测试通过,真实 HTTP Chat action smoke 通过。源码与提交后的 tree 一致。远端新 head 的 CI 正在重新运行;旧 head 的失败不等于新 head 已通过。已补跑同一份主干原版浏览器脚本:在干净的 6c0a43c34 与产品实现 head 8946ef29f 分别执行打包界面,两边均 24/24 通过,完整 acceptance-results JSON 一致,没有删掉诊断、说明或其他语义字段来制造相等。脚本 SHA256 为 002e08416fceb69a888cb79132cc4aaed3ac0d34e4b92cb15e31ebe509eff05d,两边结果的 canonical JSON SHA256(仅按键排序、紧凑序列化)为 78e5fab74a1e2c9ad4f8fad00342e5e451b8eb2fbd72fab8fd4a8f0ef202eeca,保存的两个 JSON 文件字节 SHA256 同为 11e1e1a1fe1e78a0a1dd46f8226b88f20494de8ecc13c1bfdd9a666651d3cd01。执行方式为在对应 checkout 打包后,以同一份主干脚本运行 LOOPX_PERSONAL_WORKSPACE_PACKAGED=1 node examples/.tmp-action-baseline-parity.mjs,使用两个独立端口;临时脚本已删除。该对照覆盖原有 24 项验收,新增异常反例另由最终 head 的完整浏览器套件验证,不宣称穷尽所有 payload。

CI 还暴露了一个测试本身的问题:恢复断言按部分文本匹配“正在整理…”时,同时选中了无障碍 live-region 与 pending span,Playwright 因 strict mode 失败。已用真实 Chromium 的两个节点确定性复现旧 selector 失败,并证明 { exact: true } 只等待 pending span 消失、保留 live-region。最新提交仅修这一行,保留原等待和恢复断言;修改后的完整开发浏览器、完整打包浏览器均再次通过,canary 再跑 12 项、失败 0 项。产品代码和 bundle 与 8946ef29f 完全相同,因此上述 baseline 配对证据继续适用;这不是忽略失败或放宽产品验收。

我的整体评价

完整 PR 的方向和规模合理:复用现有写入与重试边界,以一个小型可派生展示计划覆盖真实用户入口,没有引入第二套状态机。本次复查修复了 generic deferred 历史 gate、apply 响应身份以及错误文案分类三个相邻问题,未借机扩展权限或目录能力。

当前没有剩余已复现的实现缺陷,但保留 REQUEST_CHANGES / 等待验证证据,原因是新 head 的 required CI 尚未全部结束;同 harness 的 baseline 对照已补齐。这个结论不是声称代码仍存在确定性 bug,也不是把作者自审包装成独立批准。合并前应读取最终 head 的完整 CI 结果,再更新结论。

@huangruiteng huangruiteng 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.

本次审阅绑定 exact head b9088302cf7f7177e3d9ddef3e91a095252a3038。结论为请求修改:纯 presentation compiler 的 ownership 和大部分状态优先级合理,但“完整、已验证的 stop 才能 direct”目前只检查 validation_evidence.length > 0;[null] 这样的无效证据会直接打开 ready_stop,这是 typed-state 的阻塞缺口。

动机

Goal stop/resume/delete 的交互应该清楚说明为什么可以直接执行、为什么需要 review,以及何时因为 stale、gate 或 readback 问题必须 refresh/repair。此前 Personal Workspace 主要把 proposal status 直接映射为 UI 状态,drawer、快捷 stop 与 apply failure 缺少同一个可解释规则。继续堆叠局部条件虽然代码更少,但会让多个入口再次漂移;一个纯 derived compiler 是更合适的最小 owner,并且不应改变 server 的 canonical lifecycle authority。

改动思路

PR 新增纯函数 compileActionReviewPlan(),从 server TypedActionProposal 派生 interaction/reason/canApply;workspaceProposal() 将它挂到 UI model,applyProposal() 执行 canApply、响应 identity 和 verified-readback 防护,ContextDrawer 只负责展示和调用既有 callback。server 继续拥有 proposal 与 lifecycle mutation authority,ActionReviewPlan 只是绑定 proposal id/source fingerprint 的 derived presentation state,不是新持久化事实或审批 authority。

正向路径是 proposal API parse → workspaceProposal() → compiler → direct stop 或 drawer review → applyProposal() → server apply/readback。gate/stale/error 优先于 nominal success;applied 只有 projection_verified === true 才进入 completed;response 的 proposal/action/Goal/operation 必须匹配。generic non-lifecycle actions 明确保留原 reviewed path。这个分层总体符合现有 owner,但 direct completeness 必须建立在语义有效的 typed evidence 上,而不能只依赖 array length。

具体改动

本次 diff 为 14 个文件、+432/-15:7 个 dashboard runtime/type/i18n 文件、3 个 smoke/contract 文件、2 份双语 RFC,以及生成 bundle/index。production source 约 136 行,focused tests 约 125 行,文档 41 行,生成 bundle 130 行;没有新增 service、store 或迁移,体量与单一 presentation slice 基本相称。active caller 已从 Personal Workspace 页面贯通到既有 apply API,不是 coverage-only 模块。

关键代码讲解

  • apps/presentation/dashboard/src/features/personal-workspace/action-review-plan.ts:7 的 compileActionReviewPlan() 集中编译 direct/review/gated/refresh/repair/completed。其 completeness 在 :28 只要求 evidence 数组非空,没有校验元素语义。
  • apps/presentation/dashboard/src/data/chat.ts:304 的 typedActionProposalSchema 把 validation_evidence 定义为 z.array(z.unknown()),因此 [null]、[{}]、[""] 都能作为已解析 proposal 进入 compiler。
  • apps/presentation/dashboard/src/features/personal-workspace/personal-workspace-page.tsx:504 的 workspaceProposal() 为每个 proposal 生成 review plan,并把未验证 applied 映射为 error;这是各 UI 分支复用规则的正确位置。
  • 同文件 :1241 的 applyProposal() 执行 canApply、pending、response identity、verified readback 和 optimistic rollback;但 :1134 的 direct stop 会直接消费 compiler 结果,因此 evidence false-positive 已经绕过 drawer review,后置 readback 不能修复错误的 presentation decision。
  • context-drawer.tsx:957 只根据 plan 展示 explanation 和 apply/recheck 控件,没有重新实现 lifecycle legality,保持了 presentation/authority 分离。

对主干的风险

P2(阻塞):一个 preview_ready、durable_write、Goal/operation 匹配并带 apply transition 的 stop proposal,只要 validation_evidence 是任意非空数组就会被判为 direct。我编译并直接调用 exact-head production compiler,输入 validation_evidence: [null],实际得到 {"interaction":"direct","reason":"ready_stop","canApply":true}。现有 smoke 只把 evidence 变成空数组,因此所有用例通过仍无法捕获这个反例。server 仍可拒绝最终 apply,且 stop 可 resume,但 PR 承诺的 client-side “validated ready stop” 已经 fail open。

最小修复是在既有 TypedActionProposal/compiler boundary 定义 evidence 元素语义:至少要求每项为非空字符串,更理想是复用 canonical typed evidence row。direct 必须要求每一项有效;增加 [null]、[""]、[{}] 和 mixed array mutation tests,任何无效元素都不能 direct,同时保留真实有效 evidence 的正例。不应再造独立 validator,因为 transport schema 正是最近的 shared owner。

验证方面,npm run smoke:action-review-plan 的 focused TypeScript compile/state matrix 通过;npm run build 的 tsc --noEmit 也通过,本地 Vite 随后因复用依赖树缺少 @fontsource-variable/geist 停止,未把它计作 product failure。远端 frontstage、desktop、browser smoke 和 test shards 成功,但 required checks/pytest/merge-gate 仍红。当前主干还已把 Personal Workspace browser smoke 拆为 scenario modules,本分支仍修改旧 monolith,git merge-tree 有真实内容冲突;修复后需要把回归移植到 current-main owner 并重跑。

我的整体评价

compiler 作为 presentation-only derived state 的位置正确;gate/stale/error precedence、generic action compatibility、response identity、verified readback 和 domain-neutral copy 都有明确价值。变更不引入新的 actor authority,也没有 scheduler/quota/prompt default-off 泄漏。当前无需扩大设计,只需把 evidence completeness 从“数组非空”升级为 typed semantic check,并将 browser coverage 整合进主干已拆分的 scenario owner。新的 exact head 需要证明 malformed/mixed evidence 全部 fail closed、合法 evidence 仍可 direct,解决 merge conflict,并让 required checks 全绿。

English verdict: REQUEST_CHANGES at exact head b908830. Validate every evidence element before direct mode, add malformed and mixed-evidence mutations, then integrate current main and rerun the required matrix.

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

songoow commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

已修复,提交 93ad4f4b7d4fe480e6505b6b70b5807e1a892075,并通过普通 merge 接入 84334f794。

TypedActionProposal 的现有 transport schema 现在要求每条证据都是非空白字符串,保留原文;编译器复用该字段 schema,避免另建验证规则。[null]、[""]、空白文本、[{}] 和混合数组均无法 direct;generic 空数组仍保留旧审阅路径。

浏览器回归已迁入主干 typed-actions scenario 和共享 fixture,保留新的 runner、导航与恢复场景。桌面和移动端从实际暂停按钮经过 API parse,验证错误反馈、零 apply 调用和状态回滚;完整开发与打包浏览器均通过。真实 HTTP 服务产出的 38 个 proposal 覆盖全部 11 类 action,经新 schema 与编译器全部通过,合法 stop 仍为 direct。

验证通过:编译器反例/兼容性 smoke、CommonJS consumer smokes、TypeScript/Chat build、完整开发及打包浏览器、最终 diff canary 15 项(0 失败)。维护者反例已在修前复现。新 exact-head CI 仍需读回,不沿用旧 head 的状态;未合并 PR。

四个更新后的 PR 已在 main 84334f794 上组合验证:共享导入和脚本键采用两侧并存,重新构建单一 Chat bundle;类型/构建、action/attention/schema/CommonJS smokes、完整开发/打包 workspace 与两个专属打包浏览器均通过。合并顺序仍需处理这些共享文件和生成资源,未发现已验证路径中的功能冲突。该工作树仅用于验证,未合并任何 PR。

huangruiteng
huangruiteng previously approved these changes Sep 12, 2026

@huangruiteng huangruiteng 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.

本次复审绑定 exact head 93ad4f4b7d4fe480e6505b6b70b5807e1a892075。结论:APPROVE。上一轮发现的 malformed validation_evidence 可以误开 direct stop,以及与 current main 的浏览器场景集成缺口,都已经修复;本轮重新覆盖完整 PR。

动机

Goal stop、resume、delete 原本在多个 UI 分支分别解释 proposal 状态:stop 在 preview ready 后直接执行,resume/delete 进入抽屉,apply error 和 readback 又在另一处处理。这样容易出现同一事实的多个解释。最强的反对理由是为一个 stop 按钮引入过度框架;当前方案把范围限制为一个小型、纯派生的 presentation compiler,服务端合法动作、指纹校验和写入 authority 都保持原样,因此比继续堆局部条件更容易验证且没有复制 Core。

改动思路

所有 preview/list/apply 响应仍先经过 typedActionProposalSchema,再由 compileActionReviewPlan() 按精确 typed facts 生成 direct、review、gated、refresh、repair、pending、completed 或 inactive。只有完整的 preview_ready、durable_write stop,且 Goal 身份匹配、包含 apply transition、每条 evidence 都是非空文本时才可 direct。resume/delete 保持 review,generic action 保留既有 reviewed/deferred retry 语义。

apply 后必须返回同一 proposal、action kind、Goal 和 operation;applied 也只有 receipt.projection_verified === true 才能显示 completed。stale 使用 error code 或 typed proposal status 判断,不再从本地化错误文案匹配。这个编译器没有写入能力,只决定 Dashboard 如何展示和是否进入现有 apply caller。

具体改动

关键代码讲解

  • typedActionProposalSchema 将 validation_evidence 从任意 JSON 数组收紧为逐项非空文本。真实 ChatActionService 的所有 producer 本来就生成文本,所以这是 transport owner 上的 fail-closed 修复,而非另建 validator。
  • compileActionReviewPlan() 明确 gate/stale/error/applying/applied 的优先级;lifecycle direct completeness 复用 transport schema。未知 operation/permission 不会可执行,generic deferred 历史 gate 不会误关原有重试路径。
  • requestGoalLifecycle() 先验证 preview 的 Goal/operation,再决定 stop 是否 direct;不能 direct 时回滚 optimistic stop 并打开现有 review surface。
  • applyProposal() 绑定 exact response identity 与 verified readback;不匹配、stale、gate 或未验证 applied 都会回滚 optimistic projection,并进入 refresh/repair/gated,而不是宣称完成。

完整差异为 16 个文件、+463/-15,其中约 130 行为生成 bundle、135 行为测试/fixture、50 行为双语 RFC。生产改动集中在现有 Chat transport 和 Personal Workspace action path,没有新增 store、服务、CLI、权限目录或迁移状态。

对主干的风险

上一轮的关键反例是 validation_evidence: [null]:旧 reviewed head b9088302cf7f7177e3d9ddef3e91a095252a3038 的真实 production compiler 返回 direct / ready_stop / canApply=true,而当前 exact head 对相同输入返回 refresh / incomplete_proposal / canApply=false,transport parse 也会拒绝它。新增矩阵还覆盖 null、空串、空白、对象和 mixed arrays;合法带空格文本保持原文且仍可 direct。

我运行了 focused smoke:action-review-plan、真实 loopx-chat-actions-smoke.py、Dashboard TypeScript typecheck 与开发/Chat 双构建,以及完整 Personal Workspace 的 navigation-sorting、chat-recovery、typed-actions 开发/打包浏览器场景,全部通过。相同共享开发场景在 immutable base 84334f794 也通过。远端 required checks(dashboard acceptance、4 个 test shard、pytest、merge-gate 等)全部为绿色。

浏览器错误响应是受控 fixture,用于证明消费者对错 identity、stale、gate 和 readback 的处理;真实 ChatActionService/Store smoke 则单独验证了生产 producer、状态转移和 receipt 边界。当前未发现未覆盖的 PR-owned blocker。

我的整体评价

这个 PR 的 ownership 和规模合理:服务端仍决定合法性并执行写入,Dashboard compiler 只把已存在的 canonical facts 转成可解释展示。上轮的细微 typed-state 缺陷已有真实 old/head mutation 证据,主干 scenario owner 也完成集成;没有靠放宽断言或只看 green CI 获得结论。

未来向检查应继续保持 compiler 为纯 presentation owner,而不要把合法动作目录或授权规则搬进前端。以当前范围看不需要额外抽象或后续阻断,因此批准当前 exact head;合并仍需单独执行 exact-head merge-readiness。

English verdict: APPROVE exact head 93ad4f4b7d4fe480e6505b6b70b5807e1a892075. The malformed-evidence direct-stop defect is fixed at the shared transport boundary: the old head maps [null] to direct, while this head rejects it and returns refresh. Exact response identity, verified readback, generic retry parity, current-main browser integration, focused and real service/store smokes, development and packaged suites, builds, and all required checks passed.

Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng

huangruiteng commented Sep 12, 2026 •

Copy link
Copy Markdown
Collaborator

Re-reviewed integrated head e81ceae8ddd2da837158b1a79d052b0b3947f426 against main fe18fd386073b973ddcd5b23fffa6c66a2a1124e. No PR-owned blocking finding remains. The owner explicitly authorized conflict resolution and maintainer self-merge.

Resolution and product judgment

The conflicts were additive imports, adjacent package script registrations and the packaged Chat entry point. Both sides are retained: action review compilation, attention details from #4247, and acceptance observations from #4248. Rebuilt the combined dashboard and replaced only this PR's superseded generated JavaScript; existing main assets remain available.

The full 16-file change is a bounded presentation compiler over existing typed Chat proposals. Validated stop keeps the direct path; resume/delete remain reviewed. Malformed evidence, stale/gated proposals, wrong response identity and unverified readback cannot become a successful completion. The server remains the legal-action and mutation owner; the new internal action_review_plan_v0 does not create a public authority protocol or another state store.

Review lenses: evidence validation reuses the transport schema, and stale classification now uses typed error codes/status rather than translated prose. Generic deferred retries retain their existing path. Default behavior changes are disclosed in the bilingual RFC: malformed evidence fails closed, and unverified applied results require repair. This feature makes no opt-in/default-off claim, introduces no scheduler obligation, and adds no permission. The existing service/store producer owners are unchanged from the earlier approved base; their real HTTP/store smoke was rerun against this integrated head. Future-facing pass: keeping the small compiler pure and reusing the transport boundary is sufficient; no additional abstraction is justified by these conflicts.

Validation

  • Dashboard TypeScript and both build outputs: passed.
  • smoke:action-review-plan: passed, including malformed/mixed evidence, independent negative fact mutations, precedence, generic retry compatibility, deterministic output and verified readback.
  • smoke:attention-details, smoke:presentation-surface-schema, smoke:usage-progress and smoke:projection-localization: passed.
  • python examples/loopx-chat-actions-smoke.py: passed over the real Chat HTTP service and local store with disposable synthetic data.
  • Full Personal Workspace development and packaged browser checks: passed all navigation-sorting, chat-recovery and typed-actions scenarios, including desktop/mobile lifecycle preview/apply failures, target mismatches and rollback. Generated exception-state screenshots were visually inspected.
  • The feat(goals): show acceptance gaps and evidence-backed progress #4248 packaged Goal acceptance browser check also passed in the combined build.
  • loopx canary premerge --from-git-diff: passed all 15 selected checks and three direct diff checks, with zero failures and zero manual holds; public/private boundary scan passed.

One additional source-text contract check remains an inherited failure: personal-workspace-contract.test.mjs:265 expects the former isManagerProjectionQuestion function text. The identical assertion fails on clean main fe18fd386 as well as this head; the referenced Dashboard source is unchanged by this PR. It is not counted as passing, and no assertion was weakened or deleted. The changed lifecycle assertions execute before that failure, and the actual Manager/navigation and lifecycle behavior is separately covered by the passing full browser suites. Initial browser launches could not discover Playwright from the repository root; explicitly selecting the already-installed dashboard package resolved setup, and all browser suites then passed.

Hosted CI for this new head is still running/queued and is not claimed as passed. The current-main conflict check is clean, no hosted failure was reported at readback, and local qualification covers the affected transport, compiler, real backend, desktop/mobile interactions, bundled consumers and public boundary. This is sufficient for the owner's explicitly authorized admin-bypass self-merge. No branch-protection policy is changed; the inherited source-text test issue is recorded above for follow-up.

Merge decision: self-merged with the owner's authorized admin bypass. GitHub confirmed merge commit 8b6152d4e2416db487d000b081c1c60a069206bc. Hosted checks still in flight at merge time are not claimed as passed.

@huangruiteng
huangruiteng merged commit 8b6152d into loopx-project:main Sep 12, 2026
7 checks passed
@songoow
songoow deleted the codex/action-review-plan branch September 16, 2026 05:54
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.

2 participants