feat(traffic): AOP traffic namespace over an always-on capture hub - #103
Open
M09Ic wants to merge 2 commits into
Open
feat(traffic): AOP traffic namespace over an always-on capture hub#103M09Ic wants to merge 2 commits into
M09Ic wants to merge 2 commits into
Conversation
The proxy hub becomes the single egress every tool routes through, and its capture becomes a control-plane operation rather than a boot flag. aop/traffic carries Configure (routing + capture) inbound and State/Flow outbound, so a host can turn recording on for a task, stream what the hub sees, and steer the egress chain live — none of which was reachable before without restarting the runner. Attribution is by connection identity, not by a time window. A caller injects the tool-call id as the proxy username; ConnContext carries it, and every flow on that connection is stamped with it. Concurrent executions no longer overlap the way a cursor snapshot let them. The reply path is the part that had to be fixed to make any of this work: Dispatch handed every namespace handler a SendFunc that discarded what it was given. The built-in namespaces close over the connection's sender and ignore that argument, so it went unnoticed — but an ExtraNamespaces handler has no such closure and could only answer through it. A runner would accept Configure, enable capture, and silently drop every State and Flow it produced, which from the control plane is indistinguishable from a quiet target. TestExtraNamespaceRepliesReachTheWire pins it open. Also in this branch, from adjacent work on the same tree: CI and release workflow updates, tmux/foreground command changes, skills and docs edits, and the archtest → internal/repositorytest move. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two directives only worked because of where this repository happens to sit on disk. `require aop v0.0.0` was a placeholder that nothing but the in-repo replace could satisfy, so no external consumer could resolve the submodule at all; it now names the published pseudo-version, and the in-repo replace stays because consumers ignore it and it keeps local development building against the tree rather than the proxy. The mitmproxy replace pointed at ../utils/mitmproxy — a path outside the repository, satisfiable by no checkout but this one. The fork patch it existed for is published now, so the requirement names it directly and the replace is gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
这个 PR 做了什么
把 proxy hub 变成所有工具的统一出口,并把「抓包」从启动期开关变成控制面操作。
aop/traffic承载入站的Configure(routing + capture)和出站的State/Flow,于是宿主可以按任务打开录制、流式拿到 hub 看见的每一次交换、并在线切换出口链路——这些在此之前都必须重启 runner 才能改。归属改为按连接身份,而不是时间窗口。调用方把 tool-call id 注入为代理用户名,
ConnContext记住它,该连接上的每条 flow 都带上这个戳。并发执行不再像游标快照那样互相串。必须先修的一处缺陷
Dispatch传给每个 namespace handler 的SendFunc是一个丢弃入参的空实现。内建 namespace 都在闭包里捕获连接自己的 sender、忽略这个参数,所以它一直没被发现;但
ExtraNamespaces注册的 handler 没有那层闭包,只能通过它回话。结果是:runner 接受Configure、真的打开了抓包,然后把它产生的每一条State和Flow静默丢掉——从控制面看,这和「目标很安静」完全无法区分。TestExtraNamespaceRepliesReachTheWire钉住了这条路径。我验证过它确实能抓到这个 bug:把reply换回丢弃实现即 FAIL,修复后 PASS。同分支内的其它改动
这棵工作树上还有几条并行的工作线,一并包含在内:CI 与 release workflow 更新、tmux/前台命令改动、skills 与 docs 编辑,以及
archtest/→internal/repositorytest/的移动。审阅时可以按目录拆开看。验证
go build:主模块(pkg/tools/core/agent/cmd/internal)与aop子模块均通过go test ./pkg/node/ ./tools/proxy/:通过未包含工作树里的运行产物(
app.js/index.js两个 1.8MB 打包文件、evidence_*.txt、port*.json、procs.*、findings/、tmp_t3/、login.json等)。🤖 Generated with Claude Code