Skip to content

fix(mesh): bind resident turns to stored transcripts - #11255

Merged
yiliang114 merged 1 commit into
codex/multi-agent-mesh-foundationfrom
codex/mesh-step-7-live-demo
Sep 7, 2026
Merged

fix(mesh): bind resident turns to stored transcripts#11255
yiliang114 merged 1 commit into
codex/multi-agent-mesh-foundationfrom
codex/mesh-step-7-live-demo

Conversation

@yiliang114

Copy link
Copy Markdown
Collaborator

What this PR does

This stacked child of #11206 fixes resident-agent continuation so the next mesh run is bound through the same persisted transcript location used when the background agent was launched. It also records the first two-agent live happy-path observation in the design and acceptance documents.

Why it's needed

The first live parent wake found that continuation looked for agent metadata below the checkout instead of the runtime project-artifact directory. The first Alice run and Bob child run completed, but Alice's second run failed before her resident body could continue. Aligning the lookup with the launcher removes that blocker.

Reviewer Test Plan

How to verify

Create a root thread addressed only to Alice. Ask Alice to create and assign a child to Bob and wait. Bob should post his result and hand the child to review; the parent report should book Alice again; the same resident Alice body should summarize Bob's result and hand the root to review. Confirm the root and child both end in review, with Alice's closes recorded as waiting then review and Bob's close recorded as review.

Evidence (Before & After)

Before: Bob completed the child and the parent report was persisted, but Alice's second run failed while binding its persisted runtime context because the metadata lookup used the checkout path.

After: Alice completed waiting, Bob completed review, the parent report was applied after 13 ms, and the same Alice body completed review on its second turn. Both threads ended in review. All six mesh thread tools were present in the real model tool surface. No mesh prompt change was required.

Tested on

OS Status
🍏 macOS ✅ live two-agent demo
🪟 Windows ⚠️ not tested
🐧 Linux ⚠️ not tested

Environment (optional)

Local TypeScript source execution with the configured OpenAI-compatible provider and two real general-purpose background agents. No build, lint, typecheck, CI, or unit-test command was run for this child PR.

Risk & Scope

  • Main risk or tradeoff: This is one runtime-path correction backed by the observed live path; it does not broaden dispatcher behavior.
  • Not validated / out of scope: Forced running-delivery misses, ping-pong limits, daemon reaping/reload, bare-mode tool exposure, restart recovery, Web Shell, and notifications.
  • Breaking changes / migration notes: None.

Linked Issues

Part of #11206.

中文说明

这个 PR 做什么

这是 #11206 的 stacked 子 PR。它修复长期驻留 agent 续跑时的绑定路径,让下一次 mesh run 从后台 agent 启动时使用的同一个持久 transcript 位置读取元数据;同时把第一次双 agent 真实 happy path 的观测写回设计和验收文档。

为什么需要

第一次真实父线程唤醒暴露出:续跑在 checkout 下寻找 agent 元数据,而不是 runtime 的项目产物目录。Alice 第一轮和 Bob 子线程都成功完成,但 Alice 第二轮在长期执行体继续之前失败。让查找路径与 launcher 一致即可消除这个阻塞。

Reviewer Test Plan

如何验证

创建一个只 @alice 的根线程,让 Alice 新建并指派 Bob 的子线程后等待。Bob 应发回结果并把子线程交回 review;父报告应再次预约 Alice;同一个长期驻留的 Alice 执行体应汇总 Bob 的结果并把根线程交回 review。确认根线程与子线程最终都是 in_review,Alice 两次收尾依次记录为 waiting 和 review,Bob 记录为 review。

证据(修改前后)

修改前:Bob 已完成子线程,父报告也已持久化,但 Alice 第二次 run 在绑定持久运行上下文时失败,因为元数据查找使用了 checkout 路径。

修改后:Alice 完成 waiting,Bob 完成 review,父报告 13ms 后写入,同一个 Alice 执行体第二轮完成 review;两个线程都进入 in_review。真实模型工具面包含全部六个 mesh thread 工具。无需修改 mesh prompt。

测试环境

OS 状态
🍏 macOS ✅ 真实双 agent demo
🪟 Windows ⚠️ 未测试
🐧 Linux ⚠️ 未测试

环境

本地直接运行 TypeScript 源码,使用已配置的 OpenAI-compatible provider 和两个真实 general-purpose 后台 agent。本子 PR 没有运行 build、lint、typecheck、CI 或单元测试命令。

风险与范围

  • 主要风险或取舍:这是由真实运行验证的一处 runtime 路径修正,不扩展 dispatcher 行为。
  • 未验证 / 不在范围:运行中投递 miss、ping-pong 上限、daemon 回收与重载、bare 模式工具暴露、重启恢复、Web Shell、通知。
  • Breaking change / 迁移:无。

关联

属于 #11206

@yiliang114
yiliang114 merged commit 19e9138 into codex/multi-agent-mesh-foundation Sep 7, 2026
42 of 43 checks passed
@qwen-code-ci-bot

qwen-code-ci-bot commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Qwen Triage finishedview run. See the stage comments in this thread for the result.

Qwen Triage 已完成 —— 查看运行。结果见本线程中的各阶段评论。

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

This PR merged while triage was in flight. The pull_request_target: opened event queued this run at open time; the author merged into codex/multi-agent-mesh-foundation at 04:22 UTC before it got here. So this is a post-merge record, not an admission decision — no approval and no request-changes is submitted, because both would be moot on code that already landed. It is still worth reading: this commit rides into main on #11206, and Stage 2 found one thing that will go red there.

Template ✓ — every required heading is present and actually filled in, including the Tested-on table and the full Chinese translation.

Problem: observed, not theoretical. The description reports a concrete live failure — the first parent wake died before the resident body could continue — with a before/after and a named root cause. Reading the code confirms the mechanism rather than taking it on faith: bindNextTurn was deriving the agent sidecar path from a different root than the code that writes it. That is a real mismatch, not a hypothetical.

Direction: aligned. This is one step of a documented, maintainer-driven build-out (the design and acceptance plans under docs/plans/), targeting the stack's own feature branch rather than main. Nothing here pulls focus or expands the dispatcher's behaviour — it makes one lookup agree with the launcher.

Size: core path touched (packages/core/src/agents/mesh/dispatch-port.ts), so the breakdown matters — production logic 2 lines (1 added, 1 deleted), docs 76 lines (60+/16−), tests 0, generated/schema 0. The title type is fix, not refactor, so the Tier 1 hard block does not apply, and the author is an admin-level maintainer, who is exempt regardless. Well under both the 500-line escalation and the 1000-line advisory. Tier 2 still applies to any core change, so Stage 2 names every downstream consumer instead of asserting the direction looks right.

Approach: scope feels right, and I could not find a smaller fix. Aligning the read root with the write root is the minimal correction; the alternative — threading the resolved meta path down from the launcher — would be a larger refactor for the same outcome. The 76 doc lines are the bulk of the diff but are not scope creep: the acceptance plan's job is recording what the live run proved and what it did not, and this PR is that run. One honest note: the code fix ships with no test, which Stage 2 turns into a finding.

Risk: no elevated risk signals — none of the three changed paths match the revert-correlated set.

Moving on to code review. 🔍

中文说明

本 PR 在 triage 运行期间已被合并。 pull_request_target: opened 事件在 PR 打开时排起了这次运行,而作者在 04:22 UTC 已把它合并进 codex/multi-agent-mesh-foundation。所以下面是合并后的记录,而不是准入判定——不会提交 approve,也不会提交 request-changes,因为代码已经落地,两者都失去意义。但仍然值得一读:这个 commit 会随 #11206 进入 main,而 Stage 2 发现了一个届时会变红的问题。

模板完整 ✓ —— 所有必需小节都存在且真实填写,包括 Tested-on 表格和完整中文翻译。

问题:已观测,不是理论性加固。 描述给出了具体的真实失败——第一次父线程唤醒在长期执行体续跑之前就挂了——并附 before/after 和明确的根因。读代码可以确认这个机制,而不只是采信描述:bindNextTurn 推导 agent sidecar 路径所用的根目录,与写入该文件的代码不一致。这是真实的错配,不是假设。

方向:对齐。这是一个有文档、由维护者推进的搭建过程中的一步(docs/plans/ 下的设计与验收计划),目标是该 stack 自己的特性分支而非 main。没有偏离重心,也没有扩展 dispatcher 行为——只是让一处查找与 launcher 保持一致。

规模:触及核心路径(packages/core/src/agents/mesh/dispatch-port.ts),所以需要拆分统计——生产逻辑 2 行(1 增 1 删),文档 76 行(60+/16−),测试 0 行,生成/schema 0 行。标题类型是 fix 而非 refactor,因此 Tier 1 硬拦截不适用;且作者为 admin 级维护者,本身即豁免。远低于 500 行升级线与 1000 行大 PR 建议线。但任何核心改动都适用 Tier 2,所以 Stage 2 会点名每一个下游消费者,而不是只说"方向看起来对"。

方案:范围合理,也没找到更小的改法。让读取根目录与写入根目录一致就是最小修正;另一条路——把解析好的 meta 路径从 launcher 传下来——为了同样结果要做更大的重构。76 行文档虽然是 diff 的主体,但不算夹带:验收计划的职责本来就是记录这次真实运行证明了什么、没证明什么,而本 PR 就是那次运行。一个客观提醒:这处代码修正没有带测试,Stage 2 会把它变成一条发现。

风险:无升级风险信号——三个改动路径都不匹配与 revert 相关的路径集合。

进入代码审查 🔍

Qwen Code · qwen3.8-max-2026-09-02

Reviewed at 31c53a14c7570c228d8fc16a65324e0b231f7780 · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Reading only the title and the "Why it's needed" section first, my own proposal was: the launcher writes the mesh agent's sidecar under the background-agent transcript root, so the continuation binder has to resolve that same root — change the one argument to whatever the launcher passes, and pin it with a test so the two cannot drift apart again. The PR does the first half exactly. It does not do the second, and that turns out to matter.

The production fix is correct

getAgentMetaPath(projectDir, sessionId, agentId) resolves <projectDir>/subagents/<sessionId>/… — the parameter is literally named projectDir (agent-transcript.ts 62–107). Every other caller passes config.storage.getProjectDir():

  • the writertools/agent/agent.ts ~3228: const projectDir = this.config.storage.getProjectDir()getAgentMetaPath(projectDir, sessionId, hookOpts.agentId); same again on the foreground path ~4092–4103
  • the resume/revive readeragents/background-agent-resume.ts ~445–469
  • dispatch-port.ts was the only caller passing config.getProjectRoot(), i.e. the workspace checkout

The nicest corroboration is buildAgentTranscriptAttach in the very same module: it uses getProjectRoot() for cwd and gitBranch (genuinely workspace-relative) and storage.getProjectDir() for getAgentJsonlPath — the transcript that the meta sidecar sits beside. The convention the fix adopts is already spelled out one function away.

Consumers, named, since this is a core-path change: bindNextTurn is called from createMeshDispatchPort().start() for every non-launch action (resume, continue_completed), whose only caller is the mesh dispatcher; the meshRun it patches is what the next turn's binding is verified against, and a read-back mismatch throws Could not bind mesh run … to its body. Before the fix it was patching <checkout>/subagents/<sessionId>/mesh-<id>.meta.json — a file nothing else reads or writes. After it, all three sites agree, and I found no remaining caller that still uses the checkout root. loadForkProfile at agent.ts ~1316 does take getProjectRoot(), correctly: that's a workspace file, not a sidecar.

One real problem: this breaks the package's own test for this file

dispatch-port.test.ts was not updated, and its fake config cannot support the new expression.

makeConfig() returns a plain object literal cast as unknown as Config, carrying getProjectRoot, getBackgroundTaskRegistry, getSessionId, reviveCompletedBackgroundAgent, resumeBackgroundAgent — and no storage (grep for storage in that file returns nothing). The cast is why typecheck stays green. At runtime config.storage is undefined, so config.storage.getProjectDir() throws TypeError: Cannot read properties of undefined (reading 'getProjectDir'). Argument evaluation happens at the call site, so the module mock on line 18 (getAgentMetaPath: () => '/mesh-agent.meta.json') does not save it. start() wraps the body in try/catch and converts the throw through failure(error, action === 'launch' ? 'launch' : 'resume'), so every non-launch dispatch returns { status: 'launch_failed', failureStage: 'resume', error: <TypeError> } instead of what the test expects:

test expects now gets
continues a completed body hot started launch_failed/resume
falls back to the transcript only when the runtime is gone started + revive called launch_failed/resume, revive never called
reports capacity before mutating anything capacity_wait launch_failed/resume
does not force a body that changed state under it failureStage: 'continue' 'resume'
treats a revive that returns nothing as a typed failure failureStage: 'revive' 'resume'
resumes a restart-recovered entry started launch_failed/resume
turns a thrown runtime error into a typed failure error: 'registry exploded' the TypeError message

All 7 createMeshDispatchPort tests; only the 2 inspectBody tests survive, because they never reach bindNextTurn. The fix is one line in the fake — storage: { getProjectDir: () => '/workspace' } — which also gives the storage root the pin it currently lacks.

Not verified by execution: running PR-derived code is out of bounds for this gate, so the above is static analysis of the code at the reviewed commit, not a vitest run. I did check it is still live rather than already fixed: the branch tip is this PR's merge commit 19e91384, and both the test fake and the changed line are unchanged there, so this is the state #11206 carries toward main.

Test evidence — the PR's own CI

There is none, and the reason is structural rather than an oversight. ci.yml triggers pull_request only for branches: ['main', 'release/**']; this PR's base is codex/multi-agent-mesh-foundation, so test, lint_and_static and everything downstream never started. Of the 73 check-runs on the head SHA, zero come from Qwen Code CI and zero workflow runs carry event == "pull_request". What ran is bot orchestration only. No unit test, lint, typecheck or build has ever executed against this commit — which matches the PR's own "no build, lint, typecheck, CI, or unit-test command was run for this child PR", and applies equally to the nine siblings already merged into that branch. The first real gate for any of it is #11206.

Check Conclusion
triage in_progress (this run)
authorize success ×1, cancelled ×1, skipped ×6
assign success
label success
delete-asset-branch success
precheck-pr skipped ×8
review-config skipped ×7
review-pr cancelled ×1, skipped ×6
resolve-pr cancelled ×1, skipped ×6
publish-resolution cancelled ×1, skipped ×6
ack-review-request cancelled ×1, skipped ×6
delay-automatic-review cancelled ×1, skipped ×6
fallback-comment cancelled ×1, skipped ×6
verify skipped
tmux-testing skipped
publish-verify skipped
publish-tmux skipped

Sandboxed verification would settle this: @qwen-code /verify on #11206, which carries this commit — the live two-agent claim (a resident Alice body actually resumes, summarizes Bob's child thread, and closes the root in review) rests on the author's report from macOS only, and no CI reproduced it. The author has write access, so @qwen-code /tmux is available too. Worth saying plainly: static review can settle the narrow path-alignment claim above, and the writer/reader agreement is provable by reading; it cannot settle the behavioural one. The cheapest useful signal here is the one-line test fix, which would have caught the regression and pins the root against future drift.

中文说明

先只看标题和"为什么需要",我自己的方案是:launcher 把 mesh agent 的 sidecar 写在后台 agent transcript 根目录下,所以续跑的绑定必须解析同一个根目录——把那个参数改成 launcher 用的值,并补一个测试把两者钉住,避免再次漂移。这个 PR 精确地做了前半部分,没做后半部分,而这恰恰是要紧的。

生产代码的修改是正确的。 getAgentMetaPath(projectDir, sessionId, agentId) 解析出 <projectDir>/subagents/<sessionId>/…,参数名本身就叫 projectDiragent-transcript.ts 62–107)。其他所有调用方传的都是 config.storage.getProjectDir():写入方 tools/agent/agent.ts ~3228(以及前台路径 ~4092–4103),续跑/复活读取方 agents/background-agent-resume.ts ~445–469。只有 dispatch-port.ts 传的是 config.getProjectRoot(),也就是工作区 checkout。最有力的旁证来自同一模块的 buildAgentTranscriptAttach:它对 cwdgitBranchgetProjectRoot()(确实是工作区相对量),对 getAgentJsonlPathstorage.getProjectDir()——而 meta sidecar 就躺在那个 transcript 旁边。这次修改采纳的约定,就在隔壁一个函数里写得清清楚楚。

下游消费者点名(核心路径改动必须点):bindNextTurncreateMeshDispatchPort().start() 在所有非 launch 动作(resumecontinue_completed)下调用,其唯一调用方是 mesh dispatcher;它 patch 的 meshRun 正是下一轮绑定校验的对象,回读不一致就抛 Could not bind mesh run … to its body.。修改前它 patch 的是 <checkout>/subagents/<sessionId>/mesh-<id>.meta.json——一个没有任何其他代码读写的文件。修改后三处一致,我没有找到仍在使用 checkout 根目录的调用方。agent.ts ~1316 的 loadForkProfile 确实用 getProjectRoot(),那是对的:它是工作区文件,不是 sidecar。

一个真实问题:这次改动破坏了该文件自己的测试。 dispatch-port.test.ts 没有同步更新,而它的假 config 支撑不了新表达式。makeConfig() 返回一个用 as unknown as Config 强转的普通对象字面量,带 getProjectRootgetBackgroundTaskRegistrygetSessionIdreviveCompletedBackgroundAgentresumeBackgroundAgent,但没有 storage(在该文件里 grep storage 无任何结果)。正因为这个强转,typecheck 依然是绿的。运行时 config.storageundefined,于是 config.storage.getProjectDir()TypeError: Cannot read properties of undefined (reading 'getProjectDir')。实参求值发生在调用点,所以第 18 行的模块 mock(getAgentMetaPath: () => '/mesh-agent.meta.json')救不了它。start() 用 try/catch 包住整个函数体,异常经 failure(error, action === 'launch' ? 'launch' : 'resume') 转换,因此所有非 launch 派发都返回 { status: 'launch_failed', failureStage: 'resume', error: <TypeError> },而不是测试期望的值——createMeshDispatchPort 的 7 个测试全部失败(详见上方表格),只有 2 个 inspectBody 测试因为不会走到 bindNextTurn 而存活。修复只需在假 config 里加一行 storage: { getProjectDir: () => '/workspace' },顺带把存储根目录钉住。

未经执行验证: 本关卡禁止运行 PR 派生代码,所以上面是对被审 commit 的静态分析,不是 vitest 运行结果。我确认过它仍然是活的、而非已被修好:分支 tip 就是本 PR 的合并 commit 19e91384,测试假对象和被改的那一行在那里都没有变化,所以这正是 #11206 带向 main 的状态。

测试证据——PR 自己的 CI:没有,而且原因是结构性的,不是疏忽。 ci.ymlpull_request 只对 branches: ['main', 'release/**'] 触发;本 PR 的 base 是 codex/multi-agent-mesh-foundation,所以 testlint_and_static 及其下游从未启动。head SHA 上 73 个 check-run 中,没有一个来自 Qwen Code CI,也没有任何 workflow run 的 event == "pull_request";跑起来的只有机器人编排任务。这个 commit 从未执行过单元测试、lint、typecheck 或 build——与 PR 自述"本子 PR 没有运行 build、lint、typecheck、CI 或单元测试命令"一致,同样适用于已合入该分支的九个兄弟 PR。它们第一个真正的关卡是 #11206

沙箱验证可以定这件事:在 #11206(携带本 commit)上跑 @qwen-code /verify——双 agent 真实闭环的说法(同一个长期驻留的 Alice 执行体确实续跑、汇总 Bob 的子线程并把根线程收尾到 review)目前只依赖作者在 macOS 上的单次报告,没有任何 CI 复现过。作者有写权限,所以 @qwen-code /tmux 同样可用。说清楚一点:静态审查能够确认上面那个较窄的路径一致性判断,写入方与读取方的一致是读代码就能证的;但它确认不了行为层面的那一条。这里最便宜的有用信号就是那一行测试修复——它本可以拦住这个回归,并把根目录钉住防止将来再漂移。

Qwen Code · qwen3.8-max-2026-09-02

Reviewed at 31c53a14c7570c228d8fc16a65324e0b231f7780 · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Confidence: 3/5 — the production fix is right and I would have written that line identically; it landed with its own package's test broken and no CI in a position to notice, and the stack has to clear that before #11206 reaches main.

Stepping back. The change matches my independent proposal on the code and misses it on the test, and that gap is the whole story here. I verified the problem exists rather than accepting the framing: the writer in tools/agent/agent.ts and the resume reader in background-agent-resume.ts both resolve the sidecar through config.storage.getProjectDir(), and dispatch-port.ts was the single outlier passing the checkout root. That is not a judgement call about intent — it is three call sites, two of which agree with each other and one of which did not. The fix is one argument, it is the minimal one, and the 76 doc lines are the acceptance plan doing its actual job rather than padding the diff.

Would I thank or curse whoever wrote this in six months? Both, in that order. Thank them for aligning the root; curse the missing pin, because the drift this corrects is exactly the drift that will recur — after this commit, still nothing in the repo asserts that the binder and the launcher resolve the same directory. The mocked getAgentMetaPath means the test suite cannot see the argument at all, so a future edit can reintroduce the bug silently. Adding storage to the fake fixes today's failure; asserting the root would fix the class.

On the pattern question, which matters more than this PR: ten PRs have now merged into codex/multi-agent-mesh-foundation and ci.yml triggers pull_request only for main and release/**, so none of them ran a unit test, lint, typecheck or build. This gate cannot see most of that, and neither can anyone else, until #11206 goes non-draft — at which point it inherits the union of every untested child in one CI run. That is a process observation for whoever owns the stack, not a criticism of this change, which is at least documented honestly about what was and was not run.

Am I being a pushover? The easy call here is to wave through a maintainer's two-line fix on a feature branch. I am not making it: there is a concrete, mechanically determined regression, and the score reflects it.

Verdict: defer — no approval, no request-changes. To be explicit about why neither gate action is taken, since both would otherwise be expected:

  • The PR merged at 04:22 UTC, before this run reached it. An APPROVE review on landed code would attest to a gate that never ran pre-merge, and a CHANGES_REQUESTED review would misdescribe a production change I believe is correct. Both are noise on a closed PR.
  • The approval guardrail is not what is holding this back: the PR is not cross-repository and the title type is fix, not refactor, so nothing here is a policy cap. 3/5 is a real reservation, and it is the test regression.
  • No approve-on-green marker is emitted — the verdict is not approve, and there are zero pending pull_request-event workflow runs on this SHA anyway.

@yiliang114 — you own this stack and are the only one who can push to that branch, so this goes to you rather than to a third-party maintainer; the PR carries no labels and no reviews, so there is no independent owner to resolve to, and escalating a one-line test fix in your own draft stack to someone without context would just be noise. Three things, in priority order:

  1. Add storage: { getProjectDir: () => '/workspace' } to makeConfig() in packages/core/src/agents/mesh/dispatch-port.test.ts, on codex/multi-agent-mesh-foundation, before feat(mesh): add persistent shared-thread agent collaboration #11206 leaves draft. One line; it turns all 7 failing tests green again.
  2. Worth running cd packages/core && npx vitest run src/agents/mesh/dispatch-port.test.ts on that branch once. I could not — this gate does not execute PR-derived code — so my Stage 2 finding is static analysis and is labelled as such. It is the cheapest confirmation available and it is a check nothing else will perform until the stack reaches main.
  3. Structural, your call: as long as stacked children target a non-main base they get zero CI. Either widen the ci.yml trigger to cover the stack branch, or run the mesh tests locally per child. Otherwise the first green-or-red signal for the ten merged PRs arrives simultaneously, and bisecting it will be unpleasant.

I did not cross-post this to #11206 — it is a draft you own and the finding is already named there in Stage 2. Say the word if you would rather it were tracked on the parent.

中文说明

Confidence: 3/5 —— 生产代码的修改是对的,那一行我自己也会这么写;但它落地时本 package 的测试是坏的,而 CI 处在无法发现这件事的位置,stack 必须在 #11206 到达 main 之前清掉这个问题。

退一步看。这个改动在代码上与我的独立方案一致,在测试上不一致,而这个缺口就是全部故事。我验证了问题确实存在,而不是采信它的表述:tools/agent/agent.ts 里的写入方和 background-agent-resume.ts 里的续跑读取方都通过 config.storage.getProjectDir() 解析 sidecar,只有 dispatch-port.ts 传的是 checkout 根目录。这不是关于意图的判断——就是三个调用点,其中两个彼此一致,第三个不一致。修改只有一个实参,而且是最小的那个;76 行文档是验收计划在做它本来该做的事,不是给 diff 灌水。

六个月后我会感谢还是埋怨写这段代码的人?两者都有,顺序如上。感谢对齐了根目录;埋怨缺少那颗钉子,因为这次修正的漂移正是会再次发生的漂移——这个 commit 之后,仓库里仍然没有任何东西断言绑定方与 launcher 解析出同一个目录。getAgentMetaPath 被 mock 掉意味着测试套件根本看不见那个实参,所以将来一次修改可以悄无声息地把这个 bug 带回来。给假对象加上 storage 能修好今天这个失败;断言那个根目录才能修好这一类问题。

关于"是否是模式"这个问题,它比本 PR 更重要:现在已有十个 PR 合入(含本 PR) codex/multi-agent-mesh-foundation,而 ci.ymlpull_request 只对 mainrelease/** 触发,所以它们没有一个跑过单元测试、lint、typecheck 或 build。这个关卡看不见其中大部分,别人也看不见,直到 #11206 脱离 draft——届时它会在一次 CI 运行里继承所有未测试子 PR 的并集。这是给 stack 负责人的流程观察,不是对这次改动的批评;至少它对"跑了什么、没跑什么"是如实记录的。

我是不是太好说话了?这里最省事的判断是把维护者在特性分支上的两行修改直接放过。我没有这么判:存在一个具体的、由机制决定的回归,分数也体现了这一点。

结论:暂缓——不 approve,也不 request-changes。 明确说明为什么两个关卡动作都不做,否则它们本该是预期行为:

  • 本 PR 已于 04:22 UTC 合并,早于这次运行到达。对已落地代码提交 APPROVE,等于为一个从未在合并前运行过的关卡背书;提交 CHANGES_REQUESTED,则会错误描述一个我认为正确的生产改动。两者在已关闭的 PR 上都只是噪音。
  • 拦住它的不是审批护栏:本 PR 不是跨仓库(fork),标题类型是 fix 而非 refactor,所以这里没有任何政策性上限。3/5 是真实的保留意见,就是那条测试回归。
  • 没有输出 approve-on-green 标记——结论不是 approve,而且该 SHA 上本来也没有任何待完成的 pull_request 事件 workflow run。

@yiliang114 —— 这个 stack 归你,也只有你能往那个分支推代码,所以这条交给你而不是交给第三方维护者;本 PR 没有任何 label,也没有任何 review,因此解析不出独立负责人,而把你自己 draft stack 里的一行测试修复升级给一个没有上下文的人,只会是噪音。三件事,按优先级:

  1. feat(mesh): add persistent shared-thread agent collaboration #11206 脱离 draft 之前,给 packages/core/src/agents/mesh/dispatch-port.test.tsmakeConfig() 加上 storage: { getProjectDir: () => '/workspace' },改在 codex/multi-agent-mesh-foundation 上。一行;它能让 7 个失败的测试重新变绿。
  2. 建议在那个分支上跑一次 cd packages/core && npx vitest run src/agents/mesh/dispatch-port.test.ts。我不能跑——本关卡不执行 PR 派生代码——所以 Stage 2 的发现是静态分析,并且已如此标注。这是目前最便宜的确认方式,也是在 stack 到达 main 之前不会有任何其他环节执行的检查。
  3. 结构性问题,由你决定:只要 stacked 子 PR 的 base 不是 main,它们就完全没有 CI。要么放宽 ci.yml 的触发条件覆盖这个 stack 分支,要么每个子 PR 本地跑一遍 mesh 测试。否则十个已合并 PR 的第一个"绿或红"信号会同时到达,届时二分会很难受。

我没有把这条转发到 #11206 —— 那是你名下的 draft,而 Stage 2 里已经点名了这个问题所在。如果你更希望在父 PR 上跟踪,说一声即可。

Qwen Code · qwen3.8-max-2026-09-02

Reviewed at 31c53a14c7570c228d8fc16a65324e0b231f7780 · re-run with @qwen-code /triage

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