Repository navigation
feat(steward): prepare native identity in the original conversation - #7127
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
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
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model=GPT-6; provider=OpenAI; self_reported (host execution observation unavailable: session_not_found)
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
受影响的是希望在原私聊中使用周期监控的管家用户。原会话没有已注册的执行身份;直接使用项目 Goal Chat 的激活入口会拒绝它。过去只能保持普通对话,本次可以在原连接上准备一个持久身份,并明确读回尚未启用定时任务。已验证的结果是一个真实原生 Goal/Agent 与原会话绑定,历史、请求和原权限保留。周期唤醒、受控 Turn、日报生成及原私聊投递仍未接入,不能把本次准备成功解释成日报已经运行。
因此我的交付判断是 justified_increment。最强的反对理由是它还没有交付用户最终需要的定时报表;这个顾虑成立,但身份创建本身修改了持久数据,适合先独立验证 File/SQLite、丢响应恢复和原会话保留,再接入会调用模型的宿主。它没有要求用户重新输入已有 App、工作区或接收人;一次操作自动完成当前预览和提交。部署负责人已有明确授权时,也可走同一原生接口,不需要额外确认轮次。
改动思路
身份选择、源验证和绑定转换属于现有 TypeScript 会话 owner;Python 只组合原生创建、存储初始化和 Agent 注册。没有复制调度器或维护另一套任务权威。只放宽现有项目 Goal Chat 的校验会把项目会话与个人管家的权限语义混在一起;单独改一个 Session 布尔值也不能提供注册、存储和恢复。这两种更小的改法均不能满足当前边界。
本次边界是通过真实设置页面准备和读回一个原生身份,后续原生宿主与周期报告继续沿同一实现接入。绑定中的 managed_actor 是“通过创建后复核并发布关联”这个事实:仅看到一个已创建 Goal,不能推断绑定已经成功,因为注册或后续源复核可能尚未完成。它保存在既有绑定中,具体 Goal、Session 和注册状态仍分别从原 owner 读回,不复制一套可写的生命周期。
| 触发 | 决策与结果 |
|---|---|
| 打开设置、读取已有连接 | 只显示可用性,不创建 Goal 或模型 Turn |
| 原私聊空闲且当前预览有效 | 创建/恢复同一个原生身份,发布引用并独立读回 |
| 排队请求、源变化、陈旧预览或外来目标 | 拒绝本次准备,保留已有请求;修复条件后重新预览 |
| 已准备后重试或刷新 | 读回同一个注册身份;定时任务仍显示未启用 |
此表来自 5cd08027c8e72ebe6686356a4c7a6803261b1a44 的控制流,仅作说明;执行证据是下述 HTTP、存储与浏览器检查。
具体改动
依据已接受的规格 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,固定版本 74651e3bec46c773f187f7eb2688962761860a12,本次映射其普通会话 checkpoint 的实际约束:
private-Core-identity:Core 持有 App/owner/source 与会话授权。实现于 typed preparation/binding owner;真实 HTTP 对外来目标、当前源和陈旧预览的拒绝已执行。ordinary-no-hidden-Goal:普通项目聊天不合成 Goal、不继承管家范围。原有项目连接的完整旧字段在相同 base/head HTTP 场景中一致;显式准备前 Goal 数均为零。original-work-continuity:原 Session、排队请求与原受众保留。File/SQLite 与 HTTP 场景验证准备后历史/Session 不变,忙碌或排队时拒绝迁移。provider-is-not-authority:provider 负责观察,类型 owner 决策。真实 provider 观察失败没有创建 Goal;恢复观察后,同一 UI 操作成功读回一个身份。implementation-vs-installed:源码、安装、真实模型与投递分别验收。本次仅资格化准备链路,原生周期宿主和真实日报投递延期到同一实现的下一阶段。
关键代码讲解
planStewardManagedMode从现有 binding、原 Session、provider 观察和当前 revision 生成预览。内部 basis 校验固定原受众、原 channel、空闲队列以及同一创建操作;已有绑定的 Goal lifetime 或 Agent 注册缺失会拒绝,而不是悄悄换一个目标。StewardManagedMode.prepare在原锁边界中组合已有 bootstrap/configure/storage owner,创建后重新检查源与队列,再发布引用。丢失注册响应时恢复同一已登记创建;对已绑定但消失的 Goal 不静默重建。普通 registry 保留原有 nullable lifetime,未伪造更强保证。prepareManagedSteward在一个明确的用户动作中取当前预览并提交,已有身份则直接读回。服务端严格限制可接受参数,调用者不能指定借用的 Goal、Agent、目录或新授权。StewardManagedMode设置控件 只在原生本人管家连接中加载,默认折叠细节;失败保留显式重试,成功明确说明定时任务未启用。已有助手和其它受众不获得这个操作。
其余改动是同一 HTTP 路由、绑定引用保留、健康投影、原生回归与使用文档。二进制截图是合成账号/上下文的实际打包设置页面,已检查像素与 PNG metadata;不包含原始私聊或本机路径。
对主干的风险
最危险的反例是旧预览在授权变更后仍能创建身份,或者丢响应重试又创建另一个 Goal。真实 HTTP 回归覆盖了前者;把当前预览校验故意删除后,同一测试实际得到 200 而期望 409,独立 oracle 失败,当前代码则通过。File/SQLite 的创建后注册失败与重试覆盖了后者。相同输入在 base 上的新路由为 404、Goal 数保持零;head 的只读预览为 200 且仍为零,显式 apply 后恰为一个,原 Session/历史和模型 Turn 数保持一致。仅移除随机 fixture 分配的身份/目录;未归一化诊断或行为差异。
原项目连接不会准备管家身份;新建的另一个管家 binding 也不会继承已准备的 actor,缺少自己的原会话时真实 HTTP 请求被拒绝。完整原会话/私聊回归 263 项通过,类型绑定回归 35 项通过;原生准备 8 项也在更新基线后通过。控制面类型检查、前端构建、Ruff、双语 RFC 检查、6 项直接检查与 16 项风险/边界检查均通过。预合并命令保留的 3 个二进制图像人工 hold 已逐一检查像素、metadata 和合成来源;不能把其 manual_review_required 原始状态称为自动通过。
语义与 CI 对齐
新引用扩展现有 native-chat 会话绑定契约,未引入另一种执行/调度权威。未准备时保留旧输入、权限、模型调用和调度路径,新增的是明确的可用性与准备入口;“可发现”不代表已经启用执行。准备后仍没有周期宿主。所查语义 advisory 没有支持形式中的新候选,但这并不能证明没有新语义,因此仍独立检查了新增持久关系的 producer、原生 owner 和恢复行为。该 Goal 的 wait_for_ci=false,本次没有查询、轮询或等待 GitHub CI。
剩余风险是未来宿主接入必须继续验证生命周期和原受众,不能仅凭这个 actor 引用启动工作。若撤销连接,现有撤销 owner 保留历史,已注册而未调度的 Goal 仍可见;本 PR 不删除它,也不借“回滚”丢弃已有请求。
我的整体评价
long_horizon=preserved:验证了原请求、Session 与可恢复创建的连续性,尚未证明长期周期工作的收益。user_experience=improved:已有信息自动进入预览/提交,失败可以在原设置重试,读回不会把准备误报成运行。已检查带普通助手与管家的混合状态、展开详情、失败恢复及 1200×888/390×844 页面;准备状态、后续动作和未启用说明均可读。未核验生产安装、自然周期触发和真实模型生成日报;这些不属于本次身份准备的验收。
代码量与“原生身份创建 + 源复核 + 恢复 + HTTP/设置读回”这个完整边界相称;决策、效果和投影仍沿现有 owner 分工,未为其增加独立 store 或版本解码分支。最有价值的简化是复用原生 bootstrap/configure 与已有绑定,不再平行实现 Goal 生命周期。基于完整 base-to-head、真实入口的正反检查及同源旧路径对比,本 exact head 无阻塞发现,建议批准此源码增量。整体日报任务继续保持未完成。
English verdict: APPROVE — exact head 5cd08027c8e72ebe6686356a4c7a6803261b1a44. No blocking findings for the source-bound native identity preparation increment. Real HTTP/File/SQLite and packaged UI checks preserve the original conversation, reject stale/foreign inputs and recover one actor without new model Turns. Three binary-image holds were manually inspected. Scheduled execution, installed adoption and daily delivery remain unqualified; CI was not consulted under the configured policy.
Problem and result
The original private steward uses a conversation identity without its own registered LoopX execution actor. That prevents native monitor Turns from owning its recurring work. This adds a source-bound Prepare steward identity action in the existing connection settings: one native Goal/Agent is registered while the original conversation, history and grants remain intact.
Preparation and scheduled execution are separate acceptance boundaries. The settings read back Scheduled tasks are not enabled after preparation. Connecting native deadlines, the managed host and daily portfolio publication remains the next stage in the same implementation, documented in
docs/product/periodic-reports.md. This boundary allows storage/identity recovery to be qualified before introducing autonomous model execution.Implementation
Validation and boundary
Visual evidence
Actual packaged settings, with a populated ordinary assistant and private steward. Desktop: 1200×888; narrow: 390×844. Feature source was tested at
97ba1e35; subsequent commits refresh these captures and trim unrelated guide history while preserving the same runtime/API/component source blobs.Before preparation:
Prepared, scheduled tasks still disabled:
Narrow layout: