Repository navigation
fix(bootstrap): validate goal ids before path construction - #7192
Conversation
Reject invalid goal IDs before deriving state paths or writing bootstrap state, so a failed request cannot leave a partial registry or state file outside the project. Signed-off-by: duang777 <duangjl007@gmail.com>
a832e72 to
2387eeb
Compare
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max
没有阻塞性发现;评审通过与合并资格分开,当前精确范围质量收据仍过期。
动机
通过 CLI 首次连接项目、显式提供 Goal ID 的使用者与调用 bootstrap 的既有产品入口。
输入含路径穿越的 Goal ID 时,基线先写注册表和越界状态文件,再返回校验错误;当前提交在构造路径前拒绝,纠正为合法 ID 后可正常连接。
相同新增回归在不可变基线失败、当前版本通过;六个真实 CLI 非法输入均在创建项目和注册表前拒绝,原位置改为合法 ID 后连接成功。
本次不改变显式状态文件权限、Goal 存储、全局同步、调度或已有验收规则,也不新增产品入口或用户确认。
改动思路
已有共享单路径校验足以保护该入口,只需前移调用;不另写规则、不改变 canonical storage 或增加第二个状态 owner。
交付 bootstrap 非法标识在任何派生路径和写入前拒绝,并保留合法首次连接;不扩展到无关存储或 UI 重构。
旧代码直到后续存储路径才检查输入,前面的注册表或状态写入已经发生。把同一校验移到原入口,在任何派生路径前拿到有效标识,可使拒绝成为无副作用的结果。合法请求仍走原 registry/state route 和 canonical creation,不需要用户再次确认,也没有另建兼容层或校验列表。
具体改动
全量2文件+42/-1;生产改动只有现有 validator 的 import 和调用位置,其余是原 CLI 回归。没有独立 bootstrap“写前校验”书面规格;本次以已独立复现的拒绝后写入缺陷和既有共享单路径规则为依据,不拿作者测试数或新断言反向定义原语义。
关键代码讲解
bootstrap_project先解析项目位置,再调用既有校验;之后才选择注册路径、现有状态路由、runtime 和存储。非法输入在 registry 事务和状态写入前返回原错误。合法默认 ID 仍由原default_goal_id生成。validate_goal_id_path_segment保持既有单一 owner,去除两端空白、拒绝空值、点目录及两种分隔符,校验本身未变化。调用其返回值后,路径与登记使用同一规范化标识。
新增回归从真实 loopx.cli.main 输入穿越 ID,检查原错误、注册表不存在以及原越界状态文件不存在。它保护的是拒绝请求的实际写入边界,不只是判断 validator 返回 false。正常首次连接与后续 registered route 仍由已有测试和原 owner 负责;没有放宽显式用户选择的 state-file 权限。
对主干的风险
最强回归场景是校验虽然报错,前面仍留下局部文件;这个差异在不可变 b8b9c1d77c17edf75e0d8860e533a7785b9bd224 同一新增回归上失败于 registry-exists,在当前 2387eeb74da2ff586ea1b136c6b9d662e68e7ccf 通过。独立六种真实 CLI 子进程输入覆盖穿越、双向分隔符和点目录,项目及注册表都未创建;同一被拒绝位置只改 ID 为合法值后首次连接成功。20个相关原用例通过,无跳过,没有触及活动 Goal 或全局登记。
语义与 CI 对齐
这是既有路径语义在正确边界的复用,没有新枚举、领域专用通用规则、模型指令或权限。更早拒绝及使用 validator 规范化后的 ID 是明确行为变化;合法连接仍复用原实现。源码 premerge6direct/3selected执行通过,汇总因 quality_stale_receipt 为 exit1,仍需精确质量资格;未把子项通过当整体绿色。作者提及的全库架构失败未由本评审重新归因,不声称已通过全库。CI waiting 关闭,未查询或等待远端 CI。
我的整体评价
完整有用的小修复达到本次 goal_achieved:长程工作减少失败输入后的脏状态和修复成本,用户体验减少额外清理,未增加操作轮次。代码量与问题相称;复用共享 helper 已是合适的有界整理,无需扩展迁移。已有共享单路径校验足以保护该入口,只需前移调用;不另写规则、不改变 canonical storage 或增加第二个状态 owner。 交付 bootstrap 非法标识在任何派生路径和写入前拒绝,并保留合法首次连接;不扩展到无关存储或 UI 重构。
已检查受影响的既有 CLI/私聊服务/设置消费者;没有页面布局、控件或折叠呈现改动,视觉变更验收不适用。 未执行完整全库套件或生产安装验收;不从本地修复推断长期成本收益。
保留精确范围质量收据、批准 closeout 和合并权限的独立门;本结论不授权合并、安装或修改无关状态。
English verdict: APPROVE at 2387eeb. The existing shared Goal ID validator now runs before derived paths or writes. The same regression fails on immutable b8b9 and passes here; 20 focused tests and six real invalid CLI vectors plus corrected-request recovery pass. Native scoped executions pass; aggregate quality qualification remains held by a stale receipt. No remote CI or merge claim.
…oal-id-boundary Signed-off-by: duang777 <duangjl007@gmail.com>
Summary
Evidence
Merge Danger
Door: two-way
The change only moves existing validation earlier in the bootstrap flow. Reverting restores the prior ordering.
Blast Radius: bootstrap
Goal And Delivered Outcome
Author Declaration
Implemented against
Scope And Continuation
Validation
Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
Boundary Checklist
Integration follow-up
2aa213fc96afd8f5a0994fed61dcbaf53af44b3d. The feature branch normally merges main at659c1fd; published history is preserved and the PR still contains only the bootstrap fix and its focused test file.tests/control_plane/test_goal_scoped_log_paths.pypasses all 19 tests. Committed-head bilingual and diff checks pass. Earlier validation below remains tied to its stated original revision.2387eeb; the updated head requires CI and exact-head review. Shared digest ownership is repaired in fix(ci): restore digest ownership and browser smoke preconditions #7209, and the independent browser smoke precondition repair is fix(tests): close analysis explicitly before changing its scope #7219. Other old Python failures remain historical until the refreshed CI completes.