Skip to content

修复 composed supervise child 无法跨包 raise(unknown namespace)#12

Merged
loning merged 1 commit into
devfrom
fix/supervise-composed-cross-package-raise
Jun 7, 2026
Merged

修复 composed supervise child 无法跨包 raise(unknown namespace)#12
loning merged 1 commit into
devfrom
fix/supervise-composed-cross-package-raise

Conversation

@loning

@loning loning commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

背景(self-hosting dogfood 发现)

首次真实启动 composed graph(github-devloop + github-proxy + consensus)的 supervise,发现一个之前从未暴露的引擎 bug:某 department raise 其 M.spec.produces 声明的跨包 queue(如 observe_issue raise consensus.proposal)时,spawn 的 child run 报:

qualified name 'consensus.proposal' uses unknown namespace 'consensus'

整个 pipeline 抛错 → 下游读不到事实源 marker → 状态机卡死转圈。mock 测试、conformance、只读 dogfood 都发现不了它——只有真实启动整图才暴露。

根因

supervise spawn child 时只传 owner 一个 package root(consumer.rsrequire_roots_for_owner(owner_root)),child 的 NameResolver 因此只认识 owner namespace。这把两个本应分离的关注点混淆了:namespace 解析(child 需知道所有 composed namespace)与 require 隔离(dept 只能 require 自己包的模块)。

修复(方案 A,thinking 三方一致)

consumer.rs 把 child spawn 的 package_roots 从 owner-only 改为全部 composed roots(package_roots().to_vec()),child 获得完整 namespace catalog;require 隔离保持不变——run 仍按 --owner-namespace 派生 Lua package.path,dept 仍只能 require 自己包模块,--package-root 不是跨包 require 授权。零新 CLI/SDK channel。

测试

  • spawn_args 传全部 composed roots / folded 单包仍单 root;
  • production run 跨包 raise 成功(旧代码 unknown namespace 失败,钉住修复);
  • require 隔离:sibling-only 模块经真实 run_pipeline require 路径不可 require;
  • supervise E2E:producer raise 跨包 → 兄弟包 consumer 消费(旧代码不投递);
  • ps 依赖改用 nix::getpgid / Rust SIGTERM→success,原断言(process-group 不等、SIGTERM 优雅退出、marker 内容)全部保留,不弱化。

cargo fmt 干净;cargo test --workspace -- --test-threads=1 全绿(22 suites)。

🤖 Generated with Claude Code

⟦AI:FKST⟧

self-hosting dogfood 首次真实启动 composed graph(github-devloop + github-proxy
+ consensus)的 supervise,发现一个之前从未暴露的引擎 bug:当某 department raise
其 M.spec.produces 声明的跨包 queue(如 observe_issue raise "consensus.proposal")
时,supervise spawn 的 child run 报 `qualified name 'consensus.proposal' uses
unknown namespace 'consensus'`,整个 pipeline 抛错、下游读不到事实源 marker、状态机
卡死转圈。

根因:supervise spawn child 时只传 owner 一个 package root
(consumer.rs `require_roots_for_owner(owner_root)`),child 的 NameResolver 因此
只认识 owner namespace,拒绝兄弟 namespace。这个 bug 把两个本应分离的关注点混淆了:
namespace 解析(child 需知道所有 composed namespace 才能 resolve 声明的跨包 raise)
与 require 隔离(department 只能 require 自己包的模块)。

修复(方案 A,thinking 三方一致):consumer.rs 把 child spawn 的 package_roots
从 owner-only 改为全部 composed package roots(`package_roots().to_vec()`),让
child NameResolver 获得完整 namespace catalog;require 隔离保持不变——run 仍按
`--owner-namespace` 反查 owner root、由 `require_roots_for_owner` 派生 Lua
package.path,所以 department 仍只能 require 自己包的模块,`--package-root` 不是
跨包 require 授权。零新 CLI/SDK channel。

测试(5 新 + 2 处等价替换):
- spawn_args 传全部 composed roots / folded 单包仍单 root;
- production run 多 root + owner-namespace 跨包 raise 成功(旧代码 unknown
  namespace 失败,钉住修复);
- require 隔离:sibling-only 模块经真实 run_pipeline require 路径不可 require;
- supervise E2E:producer raise 跨包 → 兄弟包 consumer 消费(旧代码不投递);
- sdk_codex 的 ps 改用 nix::getpgid、supervise_smoke 的 ps 自杀改用 Rust
  nix SIGTERM→success,原断言(process-group 不等、SIGTERM 优雅退出、marker
  内容)全部保留,不弱化覆盖。

SPEC.md / docs/architecture.md 同步:composed graph 的 child run 接收完整
package roots 用于 namespace 解析,Lua require roots 仍由 owner namespace 限定。

测试:cargo fmt 干净;cargo test --workspace -- --test-threads=1 全绿(22 suites)。

⟦AI:FKST⟧
@loning loning merged commit ac25b3c into dev Jun 7, 2026
4 checks passed
@loning loning deleted the fix/supervise-composed-cross-package-raise branch June 7, 2026 08:17
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.

1 participant