Repository navigation
refactor(coordination): decouple CLI and cold import from shadow producers - #6197
Conversation
…ucers 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, gpt-6.1-sol, OpenAI, runtime_reported, xhigh
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Exact head: d248dd5fdae93c0c71daf09037dab659731b5903. Reviewed the complete 21-file diff; no blocking finding for this bounded slice.
动机
准备创建新 Goal 或导入旧 Markdown Goal 的 CLI 使用者会遇到这个问题。旧 shadow 是此前用于同步旧状态的辅助链路。移除其中四个模块后,旧版 CLI 在真正处理命令前就报导入错误;本次改动后,新 Goal 的 SQLite 创建、旧数据导入及迁移后的写入恢复可以继续执行。实测源代码和正常安装包都能在四个旧模块缺失时完成这些操作,已有配置、来源身份和历史恢复义务保留。本 PR 不删除仍有调用方的 producer,不改变默认 provider,也不宣称发布或核心开发者试用验收完成。剩余工作是让真实旧调用方退出,再按既有 T4 条件删除 producer;Host 停写、完整历史和 outbox 的原验收仍然保留。
改动思路
配置和完整来源采集是迁移必须保留的行为,producer 的同步副作用属于另一条调用路径;复用已有 owner 可以去掉启动依赖,同时避免复制决策。当前 PR 交付普通 CLI 与旧 producer 的隔离和真实恢复验证;实际 producer 删除仍由既有 T4 调用方退出条件控制。入口仍是完整 CLI,配置以当前注册 Goal 为准;Python 留在既有配置适配、物理文件和锁读取职责中,来源组装与 authority 事务继续由既有 TypeScript owner 决策。只改两个 CLI 的延迟导入仍会留下 configure-goal、lease 和导入来源采集的启动依赖,因此需要一并改真实调用方;另建通用框架或复制一套判定都没有必要。冷导入走原有 prepare/apply/recover 和备份、停写检查,显式旧命令保留原 producer,缺失则按原异常边界给结构化失败。
具体改动
18 个配置/来源函数或类移入两个已有模块,AST 等价,仅两处移除自导入;旧实现删除,真实兼容调用所需的 reexport 保留。CLI 调度、configure-goal、task lease、writer fence 和两处 App storage wrapper 改指向保留 owner。authority-shadow 把 adapter/outbox 导入纳入错误边界,保留 OutboxError、锁超时和普通异常的先后处理;5 秒 CLI drain 超时仅归位、数值不变。源码/安装包测试物理移除四个 producer,并验证导入后新增 Todo、受 lease 保护的更新、原操作恢复及返回 File。两份 RFC 更新当前边界;生成 IO 清单只是调用站点迁移,仍为 291 站点、零未分类。全 diff 为 642 行新增、531 行删除,主体是代码移动和聚焦负例,不是新增平行决策。
关键代码讲解
resolve_coordination_runtime_shadow_config:Exact Goal-scoped opt-in。loopx/control_plane/coordination/configuration.py:171;Moved unchanged from runtime_shadow; default absent/false remains off;Only enabled is True plus exact schema/file_v0 enables。build_runtime_shadow_source_snapshot:Complete Host source capture。loopx/control_plane/coordination/authority_source_capture.py:114;Moved unchanged except eliminated self-imports; full snapshot/archives retained;Registry witness scope, safe lease byte reads and complete archive dependencies。handle_coordination_shadow_command:Dispatch independent import and gated legacy actions。loopx/cli_commands/coordination_shadow.py:234;Cold/recovery/inspect-source do not load producer; exact disabled check precedes lazy import;No provider discovery or other Goal can enable this Goal。handle_authority_shadow_command:Explicit authority-shadow status/drain IO。loopx/cli_commands/authority_shadow.py:137;Adapter/outbox import inside handler try; unrelated startup independent;Inner OutboxError and outer lock/generic diagnostic precedence retained。
规格基准是改动前已接受的 docs/architecture/rfcs/typescript-control-plane-migration-v0.md,revision 8d5a6fc170422ff4ff78818898b172064b1e1591。Current delivery frontier:本次 producer 隔离与现有 owner 复用已实现。Validation and stop rules for every card:真实入口、实际 File/SQLite、安装包、合法/拒绝/恢复及主干反例已执行。T4:完整退役仍 deferred,剩余真实 capture/outbox/Host 调用方退出条件不以这次 import 隔离替代。
对主干的风险
最危险的反例是普通命令已经能启动,但迁移后新增写入再恢复仍碰到旧模块或被旧来源覆盖。加强后的 File/SQLite 四个原操作恢复用例在源码和正常 wheel 均通过,并拒绝无 lease 写入;新 SQLite Goal 的创建、更新、slot 单次消费/重放、活跃 lease 阻止退出、释放再返回 File 也通过。旧 producer 存在时的命令和 outbox 恢复在 241 项相关 Python 验证中通过;源代码先前聚焦 130 项、加强后恢复 4 项,wheel 22 项加恢复 4 项均通过。不可变主干 0df53a13 对同一最终测试/fixture 有 6 个正常路径通过、9 个物理删除反例在启动处失败,证明当前新增负例能抓到真实旧缺陷。
关闭行为没有通过删除 feature 对象来推断:9 组完整 CLI 帮助/拒绝输出主干与 head 字节相同,功能关闭时无 authority-transition 写入;实际六调用对照验证同目录未启用 Goal、新建 Goal 和 Todo 注释不能继承或绕过启用范围,经正式配置启用后 bootstrap applied、读回 matched。开启的旧命令仍用原 owner,显式缺失 producer 的三个用例返回结构化错误且持久文件字节不变。没有新 schema、actor 生命周期、执行权限或默认 provider;动态缺模块诊断变化已明确披露。
语义与 CI 对齐
复用现有配置/完整来源/receipt 语义,无新增共享词汇,也无提示词压缩或将硬义务改称 guidance。完整 TypeScript 4,395 通过、零失败,37 个环境条件跳过已披露;typecheck、配置 mypy 19 模块、Ruff、完整语义漂移、IO census 及 canary 19 项均通过,CQR 通过。按当前 review 契约不查询远端 CI。Python import/config/Host 移动没有改 PostgreSQL 事务、provider 选择或 TS 规则,因此本 slice 不申请 PostgreSQL/D2 资格;也不把跳过或未测当成通过。无新前端能力或视口变化,已有 Chat storage/import 后端用例通过。没有对活跃 Goal 做损坏/提升测试。
我的整体评价
long_horizon=improved:真实原操作重放和迁移后新增写入可以继续,数据/身份/receipt 与单次效果约束保留。user_experience=improved:无需新增确认或重复录入,普通任务不再被可选旧模块缺失阻断,显式旧命令失败可读。兼容 reexport 有现存消费者且共享唯一实现,历史格式保留与保留所有旧 writer 是不同义务。本 PR 的相关未来重构已在最近 owner 内落实,进一步删除保持既有 T4 验收;无额外框架或凭空 successor。
结论是 justified_increment,这一隔离与恢复切片完整、可审查、可代码回滚;并不完成全量 Python 退役或发布。剩余风险是 live producer 的最后调用方、Host/outbox/完整历史出口和后续试用资格,仍由原验收覆盖。当前 exact head 无阻塞;若调用方、来源/事务格式或默认策略变化,需重做对应真实入口反例。runtime 改动仍待 maintainer 合并。
English verdict: APPROVE - head d248dd5; a justified T4 isolation increment with retained configuration/source ownership, real File/SQLite and installed-wheel recovery, full affected 241 Python checks and 19 canary checks passing. Live producer retirement and rollout qualification remain deferred; no new default or authority is granted.
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: actor_kind=model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=xhigh.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Exact head: d248dd5fdae93c0c71daf09037dab659731b5903; immutable comparison base: 8d5a6fc170422ff4ff78818898b172064b1e1591. This is a full independent review of the current PR, not an inherited approval.
动机
使用 CLI 创建新 Goal(持久工作目标),或从旧文件导入并恢复工作的操作者,会在命令入口遇到旧 shadow producer 的导入依赖;shadow 是迁移期间保留的兼容捕获路径。
在可丢弃副本中删除四个旧 producer 后,基线连创建/冷导入入口都可能因 ModuleNotFoundError 退出;本 head 仍能通过真实 CLI 完成 SQLite 创建、租约写入、一次结算及可逆退出,并完成 File/SQLite 导入与原操作恢复。
已验证的改进是:普通工作与完整源捕获不再要求旧 producer 存在;显式 shadow 操作缺少 producer 时返回结构化失败并保持源状态不变。
本 PR 不宣称彻底删除仍有调用者的旧 producer,不改变 App/Lark 配置契约、provider 事务、宿主安装或长期 cohort/D2 验收。
剩余缺口是现有 T4 清单中的 enabled capture、outbox 和旧命令的最后调用者退出,以及它们各自的持久性和迁移窗口验收。
改动思路
将已有配置解释和完整源读取收回现有 owner,并让显式旧命令延迟加载 producer,是解决已复现依赖问题的最小完整边界;新增并行决策源或立即删除仍有调用者的 producer 都不合理。
当前 PR 交付普通 CLI/冷导入的依赖解耦及失败/恢复契约;最后调用者退出与共享 provider 持久性验收继续归现有 T4/D1–D3 owner。
反对立即交付的最强理由是:可能只是搬代码,仍经其他入口导入旧 producer,或把完整读取与安全校验拆开。独立基线/head 与正常 wheel 的实际入口验证排除了这个局部风险。仅延迟 CLI 导入不能覆盖创建、配置、租约、prose fence 和 Chat 源读取的旁路依赖;保留旧模块中的同名 re-export 是为了真实现存调用者,并没有保留两份配置或捕获规则。
规格依据为 docs/architecture/rfcs/typescript-control-plane-migration-v0.md,不可变 revision 8d5a6fc170422ff4ff78818898b172064b1e1591,按改动前文本判断:T4 的最后调用者退出仍 deferred,永久渲染、验证后的 import/export 和外部效果 adapter 继续保留;Validation and stop rules for every card 在本次相关范围已 implemented。后者要求独立合法/非法 oracle、基线对比、真实 CLI/provider、TS 检查和风险 canary;真实 PostgreSQL 是共享事务变化的条件,本 PR 未改该事务 owner,不能把其 37 项条件跳过算作通过,也不把整条父路线设为本次入口解耦的前置门槛。
具体改动
关键代码讲解
resolve_coordination_runtime_shadow_config:纯配置解释移回既有 owner,仍要求精确 schema、provider 和enabled is True;安装/发现命令不会启用能力。build_runtime_shadow_source_snapshot:完整源读取与 registry witness 放在同一边界,保留归档全文、原操作历史和安全 lease 读取;分类/admission 仍由已有 typed TS owner 决定。handle_coordination_shadow_command:冷导入、源检查和历史恢复先走保留路径,enabled 旧动作在 L348 才加载 producer;缺失模块通过公共错误 envelope 返回。handle_authority_shadow_command:仅显式命令加载 adapter;保留 OutboxError 与 lock 的错误归属。显式 off-state 观察可加载 adapter,但不启用/创建 shadow store。
全部 21 个文件已分类:production +510/-492(净 18),tests +98/-29(净 69),docs +24,generated census +10/-10。18 个迁移定义的 AST 等价,仅忽略位置及移除 wrapper 的旧 self-import,不归一化条件、常量或文本。未来维护的相关简化已经应用:配置与源读取各归一个现有 owner;仍有真实调用者的 producer 删除继续按 T4 执行,无需增加新跟踪任务。
独立验证(Python 3.14.8 / Node 24.21.0;实际 checkout 与 child package provenance 已确认):
- 8 个相关 source/CLI/Chat storage 文件 211 passed;真实 File/SQLite,包含创建→拒绝无租约写入→获得租约→写入/一次结算→可逆退出,以及导入→后续写入→原操作恢复。完整归档/terminal lease、registry race、unsafe source、backup corruption 和 HTTP unavailable/fresh-plan/restart 也通过。
- retained enabled shadow / local authority / cold inspection 三文件 44 passed。这不是声称 producer 已删除。
- 将同一冷导入/SQLite source-removal oracle 指向基线:9 expected failures / 6 passed / 10 deselected,失败具体为命令 bootstrap 的 eager
ModuleNotFoundError;head 同一 oracle 在 211-pass 集合中通过。显式缺少 producer 的负例还验证结构化失败与源字节不变。 - 正常 dashboard
build:chat后正常uv build --wheel,安装到隔离环境;12 个 production 文件与 head 相同,正常 wheel source-removal/prose 子集 16 passed / 61 deselected。wheel SHA-25609aef2c36d8e2a77aad5124de779074c7cf235b03ca3746af0e0dda7f77158d5,子进程确认读取 installed package,未借用 source checkout,也未绕过前端构建。 - 基线/head 的 10 个公共 help/rejection 完整 stdout、stderr、exit 逐字相等。相同 unconfigured fixture 的 authority status/drain 完整 payload 也相等,Goal/registry/runtime 字节不变且不创建 store;两项探针均不归一化输出。
npm run typecheck:control-plane通过;npm run test:control-plane4395 passed / 37 conditional PostgreSQL skipped。configured Ruff、mypy 通过;风险canary premerge --from-git-diff --git-diff-base 8d5a6fc170422ff4ff78818898b172064b1e159119 smokes + 5 checks 全通过,0 failures / 0 manual holds;development advisory 12 paths/0 supported carriers(不涵盖动态/未支持语法),完整 semantic smoke 通过,registry census 291 sites current。没有查询或等待 CI。
初始 reviewer setup 曾选错不存在的测试文件(没有测试运行)、误用 semantic --check,以及缺少 Chat bundle/依赖链接失效;已按正常命令/构建恢复后完成以上独立验证,没有修改产品代码、减弱断言或绕过预算。没有将历史 setup 失败冒称为本 PR 修复的产品故障。
对主干的风险
语义与 CI 对齐
没有阻塞发现。 默认 off 的 schema、inputs、guidance、完整输出、持久状态及外部效果保持既有契约;source inventory 不授予 import/promotion 权限,旧 receipts/archive/lease 安全要求也没有删减。更改的正是普通入口的依赖及显式缺失模块的可观察失败,而非 scheduler/quota、actor 生命周期或 provider 事务。现有 Chat storage HTTP 实际 owner 与恢复路径已覆盖,没有新增前端/Lark 设置或可见 UI,故本次没有新 viewport 验收或本机 installed cohort 声明。
非阻塞 P3 — RFC 对 producer 加载范围的描述应更准确。 docs/architecture/rfcs/typescript-control-plane-migration-v0.md:118 的 “only explicit enabled shadow actions” 与显式 authority-shadow status/drain 的 off-state 观察不完全一致:它仍加载 adapter/outbox。实测返回相同 disabled/nothing_pending,源状态不变、store 不创建;这不是 off-state activation 回归。建议英中文 checkpoint 明确:普通/冷路径隔离,coordination 旧动作在 enabled gate 后加载,而显式 authority 观察可在 off 时加载 adapter。现有 off-state/missing-module 测试应保留。
最强剩余验证缺口是未执行的真实 PostgreSQL/长期 cohort 与最后调用者退出;它们属于另一个明确 owner/阶段,本次未改共享事务且不宣称完成。相关 producer 仍在线,不能据此 PR 直接删除;也没有宿主升级或合并授权。
我的整体评价
本次是 justified_increment:解决已复现的真实入口依赖问题,并保留后续写入/恢复,结构上消除了旧模块中的重复定义。long_horizon=improved:后续写入、一次结算、原操作重放继续可用;user_experience=improved:普通任务不再需要保留旧模块或额外开启配置,真实 HTTP unavailable/fresh-plan 恢复保留。完整控制面迁移未完成,但这段边界已经独立有用、可测试、可回退。上述 P3 是文档精度建议;没有需要本 PR 先修的阻塞简化、权限或运行时问题。
English verdict: APPROVE - the dependency-isolation slice has independent real CLI, negative, replay and normal-wheel evidence; the checkpoint wording suggestion is non-blocking. This COMMENTED author-account fallback is a published code approval conclusion, not formal GitHub self-approval or merge authority.
Motivation
Operators creating a persistent Goal or importing/recovering old files encountered legacy shadow-producer imports before CLI dispatch. Removing four obsolete producer modules reproduces eager ModuleNotFoundError failures at the immutable base. This exact head completes normal SQLite creation, leased writes, once-only settlement, reversible exit, and File/SQLite cold import/original recovery without those modules. An explicitly requested missing producer fails structurally without changing the source.
The delivered outcome is dependency isolation for ordinary work and full source capture. It does not claim full producer retirement, App/Lark contract changes, provider transaction changes, host installation, cohort adoption or D2 completion. Existing enabled capture, outbox and legacy callers still require their T4 last-caller exit and durability/migration-window acceptance.
Design
The smallest cohesive solution reuses existing configuration and source-capture owners, removes producer-owned copies, updates ordinary callers and lazily loads explicit legacy dispatch. Lazying only CLI registration leaves independent creation/configuration/fence/lease/Chat dependencies; deleting live producers would break retained consumers. No parallel decision source, daemon, capability, protocol or persisted state is introduced. Filesystem transport stays Python; source/archive admission and canonical transactions remain the existing typed TS owner.
I judged the accepted pre-change docs/architecture/rfcs/typescript-control-plane-migration-v0.md at 8d5a6fc170422ff4ff78818898b172064b1e1591. T4 full-writer retirement is deferred to its live callers. Validation and stop rules for every card are implemented for this slice with independent legal/illegal oracles, real CLI/File/SQLite, paired baseline/head evidence and required risk checks. Real PostgreSQL is conditional on shared transaction changes, absent here; its skips remain explicit gaps rather than passing evidence. The delivered boundary is independently useful/reversible without requiring the entire parent migration.
Concrete changes and evidence
The four linked symbols above cover explicit config interpretation, witness-bracketed complete source capture, cold-first dispatch, and explicit authority dispatch/error ownership. Exact schema/provider/boolean gating, full archived text/history, safe leases, source drift refusal and original receipts are preserved. All 21 paths were classified: production +510/-492, tests +98/-29, docs +24, census +10/-10. Eighteen relocated definitions are AST-equivalent except positions and the removed wrapper self-import. The future-facing simplification is already applied: one existing owner for each retained rule, with compatibility re-exports only for live consumers.
Independent Python source/CLI/real storage HTTP coverage passed 211 cases; retained enabled shadow/inspection coverage passed 44. The same removal oracle at base failed 9 expected eager-import cases while 6 passed (10 deselected); the head oracle passes within the source suite. A normally built and independently installed wheel has all 12 production files identical to head and passed 16 selected cases (61 deselected), including physically absent producers and verified installed-child provenance. The wheel digest and runnable commands are above. No frontend build bypass or live Goal promotion was used.
Ten complete help/rejection outputs matched byte-for-byte between base/head. Identical disabled authority status/drain outputs also matched with no source/runtime effects or store creation; no output normalization. Typecheck passed, TS tests passed 4395 with 37 conditional PG skips, configured Ruff/mypy passed, and risk premerge passed 19 smokes plus 5 checks with no failures/holds. Development semantic advisory is syntax-limited; the full semantic check and 291-site IO census also passed. CI was not queried or awaited. Initial local setup errors were resolved through normal test/build preparation, without product edits, relaxed assertions or budgets; current evidence independently covers the invariant.
Risk to main
There is no blocking finding. Off-state schemas, inputs, guidance, output, source bytes and effects preserve the existing contract. Discovery/source inspection does not grant activation/import/promotion authority. Real later-write/replay and storage HTTP restart/unavailable/fresh-plan recovery are covered; no visible UI, frontend setting or Lark entrypoint was added.
The optional P3 at RFC L118 is descriptive: explicit authority-shadow status/drain still loads its adapter/outbox even when disabled, while it returns unchanged disabled/nothing-pending observations with no activation or store. Clarify both checkpoint languages to distinguish ordinary/cold isolation, enabled coordination dispatch, and explicit off-state authority observation; retain the tests. Unrun PostgreSQL/cohort acceptance and live producer retirement are explicit separate-stage limitations, not a claim of completed migration or installed host behavior.
Overall assessment
This is a justified incremental delivery: a reproduced ordinary-entrypoint blocker is removed while subsequent work/recovery and authority remain intact, using the nearest existing owners. No current blocking repair or unjustified mechanism was found; the documentation clarification is non-blocking. APPROVE for the exact head. The author-account COMMENTED record does not merge this control-plane change or authorize host upgrade.
Normal CLI startup and cold import eagerly loaded four legacy shadow producers, so removing any of them broke unrelated canonical work before dispatch. Move retained configuration and complete source capture into their existing coordination owners, point active callers there, and load legacy producers only for an explicit shadow action. Keep current legacy commands and import-compatible APIs; provider transactions, defaults, source guards and receipts retain their existing owners.
This closes a T4 caller-isolation blocker toward canonical SQLite and eventual last-caller deletion. It preserves valuable legacy details: exact source/registry identity, archive dependencies, safe lease reads and recovery of writes made after import. Update both RFC checkpoints with the delivered boundary and remaining producer exits.
Validation:
0df53a13: 6 present-producer journeys pass; 9 absent-producer cases expose the original startup defect.CLI imports and existing App configuration/storage adapters change; no new frontend/Lark capability or configuration switch. Existing Chat storage/import tests cover the adapter owner. This does not delete live producers, qualify PostgreSQL/D2, or certify installed cohort/release adoption. Maintainer merge remains required.
Author:
model_agent, OpenAI GPT-6 family; exact current runtime label is not asserted here.Implemented against
docs/architecture/rfcs/typescript-control-plane-migration-v0.md(T4 stop rules and current delivery frontier), revision8d5a6fc170422ff4ff78818898b172064b1e1591:configuration.py,authority_source_capture.py; extraction parity and source/wheel real pathsValidation declaration: revision
d248dd5fdae93c0c71daf09037dab659731b5903; synthetic fixtures and disposable real File/SQLite runtimes (Node v24.21.0; SQLite 3.53.4). No live Goal was promoted or damaged for testing. Full affected Python suite: 241 pass, zero failures, including real Chat storage/import and enabled shadow/outbox recovery. All selected source/installed checks are finished. Canary: 19 pass, zero failures/manual holds; current change-quality receipt passes.Shared-authority fixture impact: snapshot/lease inventory shape, domain fields, validation order, compatibility projection and provider transactions unchanged. PostgreSQL three-arm promotion rehearsal is not applicable to this CLI/config/Host import-only slice; PostgreSQL and D2 qualification are not claimed. UI impact: none; no viewport, navigation or new caller-facing capability.
Boundary checks: explicit paths staged, public-safe aggregate evidence only, no credentials/private state/local paths/raw logs, signed-off commit. Future-facing refactor applied in the owning boundary; further producer deletion stays with existing T4 work. This complete isolation slice is reversible without a persisted-state format migration.