- 即时通讯
- 后端
【免费下载链接】WuKongIM
More than just IM 不只是即时通讯(IM)
WuKongIM 仓库将所有 Bug 报告、需求(PRD)与工程技能的发布动作统一收敛到 GitHub Issue,并以ghCLI 作为唯一操作入口。本文以docs/agents/issue-tracker.md为核心,结合仓库中的bug.yml模板、Issue Agent 工作流、策略文件与源码实现,系统讲解 Issue 追踪约定、Bug 提报的语义约束、授权边界、自动化修复流水线以及仓库侧配置方法。读完本文,你将掌握如何在 WuKongIM 仓库正确提报 Bug、如何理解ready-for-agent标签与/agent fix指令的真实含义,以及整套"从 Issue 到 Draft PR"的安全自动化链路是如何设计与落地的。
1. 为什么 Issue 追踪只依赖 GitHub
仓库的 Issue 与 PRD 全部以 GitHub Issue 形式存在,文档明确要求:在本仓库 checkout 目录内使用ghCLI 操作 Issue,这样仓库地址会直接从git remote推断,无需每次手动指定--repo。
一个关键约束是:Pull Request 不是本仓库的请求或分诊面(request/triage surface)。也就是说,需求、Bug 或任何待处理事项都必须以 Issue 形式进入流程,PR 只承载最终的代码变更结果,不承载诉求表达。这条约定让"问题追踪"与"代码变更"两个管道彻底分离:Issue 负责描述与授权,PR 负责交付与评审。
2. 基础约定:gh CLI 的六类标准操作
docs/agents/issue-tracker.md给出了与 Issue 生命周期一一对应的命令约定:
| 操作 | 命令 | 说明 |
|---|---|---|
| 创建 Issue | gh issue create | 交互式填写标题、正文与标签 |
| 查看 Issue 及评论 | gh issue view <number> --comments | 展示 Issue 正文与全部评论 |
| 列出并过滤 Issue | gh issue list | 可按 label、state 等条件过滤 |
| 添加评论 | gh issue comment | 用于追问信息、状态更新 |
| 添加/移除标签 | gh issue edit | 管理bug、needs-triage等标签 |
| 关闭 Issue | gh issue close | 终结一个 Issue 生命周期 |
3. Bug 报告模板:三个必填语义输入与三个可选字段
Bug 报告统一使用仓库根目录下的.github/ISSUE_TEMPLATE/bug.yml。模板的设计理念是:只保留三个必需的语义输入,其余字段尽量可选,降低提报门槛,同时确保进入 Agent 流程的每一个 Issue 都具备可复现与可判断的基础信息。
三个必填(validations.required: true)字段:
- Environment, topology, and client(环境、拓扑与客户端):简要描述部署方式、操作系统与客户端/SDK 版本。模板中的拓扑可选,缺省时按单节点集群处理;
- Reproduction steps(复现步骤):给出能稳定复现问题的最短步骤序列(模板占位符即
1. Start... / 2. Connect... / 3. Send...); - Expected and actual result(预期与实际结果):分别说明期望行为与观察到的实际行为。
三个可选字段:
- Affected version(受影响版本):推荐填写精确的 release tag 或完整 commit SHA(模板明确禁止写
latest)。留空时,默认使用维护者授权时刻的main最新提交; - Frequency(出现频率):下拉选择
Every time/Intermittent/Happened once; - Logs or configuration(日志或配置):以 shell 代码块渲染,模板反复强调需脱敏凭据、令牌、私聊消息等私有数据。
模板开头的说明文字同样要求提报者"不要包含凭据、访问令牌、私聊消息或其他私有数据",这一点与后续 Agent 的上下文边界设计一脉相承。
4. 授权模型:谁可以触发 Agent,什么文本算授权
Issue 追踪文档中最容易被误读的一条是:ready-for-agent是 Controller 拥有的运行时跟踪标签,不是授权。它只在某个 Issue 存在活跃 Agent 工作时被 Controller 添加,在终态持久化后移除,标签本身不授予任何执行权。
真正决定能否触发自动化修复的规则如下(详见 docs/agents/issue-agent.md):
- 自动开始:Issue 作者当前拥有
write、maintain或admin权限时,可自动开始工程任务; - 手动授权:其他报告人需要在第一行以精确文本
/agent fix发起,且该动作人的权限会被重新读取(每次执行都重新核实,而非缓存历史结果); - Issue 正文、引用的命令文本、普通评论、模型输出一律不构成授权。
除/agent fix外,还定义了三个控制命令:
| 命令 | 作用 |
|---|---|
/agent retry | 在needs_human之后发起一次全新的临时尝试 |
/agent cancel | 停止自动工作 |
/agent take-over | 将 Agent 分支移交给人类接管 |
此外,只有满足[BUG]标题前缀 +bug标签 + 三个必填表单区块齐全的未关闭Issue 才会进入工程流程。权限 API 的瞬时失败最多重试 3.1 秒;确认无写权限则等待,无法解析的 API 失败会中止调和(reconciliation)。
5. 五级 triage 标签体系
工程技能统一使用五级 canonical triage 角色,每个角色在本仓库中映射为同名标签,见 docs/agents/triage-labels.md:
| Canonical 角色 | 仓库标签 | 含义 |
|---|---|---|
needs-triage | needs-triage | 需要维护者评估 |
needs-info | needs-info | 需要报告人补充信息 |
ready-for-agent | ready-for-agent | 信息完备、可供 Agent 处理 |
ready-for-human | ready-for-human | 需要人类实现或判断 |
wontfix | wontfix | 该请求不会被处理 |
当技能文档指名某个 canonical 角色时,落地到仓库就是打上对应的同名标签。
6. Issue Agent 端到端流水线(源码视角)
Issue Agent 的整体行为可以概括为:像一个内嵌在 GitHub Issue 里的资深工程师——对于"已授权、足够具体、低风险"的 Bug,它复现症状、记录证据、定位根因、做最小修复、跑测试,最终打开一个完整的 Draft PR,并由人类评审与合并。下面按流水线各阶段结合源码与工作流文件展开。
6.1 事件触发与 Controller 调和
入口工作流是.github/workflows/issue-agent.yml,它订阅issues(opened/edited/labeled/unlabeled/reopened/closed)、issue_comment(created/edited/deleted)、PR 信号的workflow_run,并且:
- 每5 分钟运行一次定时调和(
schedule: cron "*/5 * * * *"); - 支持
workflow_dispatch手动输入精确的issue_number触发单 Issue 调和; - 整个工作流
permissions: {}(默认零权限),工作内容由cmd/wkissueagent二进制承担。
Controller 阶段的关键设计是**"事件载荷只是唤醒提示,决策永远基于当前 GitHub 事实"**:工作流先 checkoutmain并构建受保护的 Controller(GOWORK=off go build -trimpath -o "$RUNNER_TEMP/wkissueagent" ./cmd/wkissueagent),再把仓库、事件、控制 SHA(git rev-parse HEAD)、当前时间写入 JSON,调用wkissueagent reconcile-github --input ...生成决策。Controller 要求其 checkout SHA 必须等于重新读取到的受保护main最新头(即control_sha),后续任务恢复、Context Builder、捕获、Verifier、Publisher 全部使用该精确 SHA;候选代码则在签名任务的精确base_sha处单独 checkout。
6.2 凭据无关的 PR 信号
PR 生命周期与 Review 事件首先经过.github/workflows/issue-agent-pr-signal.yml。该工作流没有任何 token 权限、Secrets、checkout、制品或候选执行,只有一个"记录事件类型"的占位步骤。它完成后通过workflow_run唤醒 Controller,且workflow_run的 ref 与来源必须是受保护的默认分支。Controller 只接受固定信号工作流名 + 一个匹配的agent/issue-NPR,随后重新读取动作人权限、未解决的 Review 线程、PR、Issue 与签名状态。设计上既不用pull_request_target,也不给 PR 合并 ref 下发 Publisher 环境,从源头杜绝了不可信代码获得高权限环境的风险。
6.3 Context Builder 与 Codex Engineer 的边界
工程师阶段由可复用工作流.github/workflows/issue-agent-engineer.yml承担,包含四个 job:recover-task(重新读取并验证签名任务状态)、context-builder(构建有界上下文包)、engineer(运行 Codex)、verifier(干净校验)。
Context Bundle 的核心思想是隔离trusted与untrusted:trusted对象包含权威、限额、任务身份、必需测试以及精确源仓库上下文文档的 blob 身份;untrusted对象包含 Issue 与评论文本——这些文本只被当作问题数据,永不作为指令。仓库内每个AGENTS.md与FLOW.md的 Git blob 身份都会从候选源版本精确冻结,Codex 在改动某个包之前必须读取适用文件(AGENTS.md递归适用且强制,FLOW.md为咨询性导航),且候选不得修改这些指令文件。
Engineer job 调用全 SHA 钉死的官方openai/codex-action(policy 中记录为 v1.11)执行一次性完整任务:
- Codex 版本
0.146.0,模型moonshotai/kimi-k3(经 OpenRouter 固定端点https://openrouter.ai/api/v1/responses),高推理强度、临时会话、workspace-write沙箱 + 公网访问; - 不发放任何 GitHub/App token、状态签名材料、云/部署凭据、Docker socket;
- 不授予commit、push、开 PR、merge 或 deploy 权限。
Codex 拥有本地 Git/搜索/编辑/构建/测试等常规工具,但其EngineerResult(包括测试声明)仅具咨询性,是否允许发布由干净的 Verifier 独立裁决。提示词模板见.github/issue-agent/prompts/engineer.md,其中明确要求:必须先复现症状或取得直接运行时证据、不得仅凭报告推断修复、每次改动后跑聚焦测试且最多三轮"修改-测试"迭代、最终输出必须恰好是一个 JSON 对象(含schema_version、outcome、root_cause、causal_path、evidence_references、proposed_risk、tests_attempted、ready等键);无法复现或根因不确定时,必须返回needs_human/failed而不是做投机性生产改动。
6.4 候选捕获与干净校验
Codex 运行前,job 会冻结一个 root 拥有、只读的源码基线(/opt/wukongim-issue-agent/baseline,由git archive HEAD展开)。运行后,一个受信任的二进制不信任 Codex 生成的 Git refs、index、attributes、ignore 规则或 commits,直接对文件系统内容做 diff,产出候选快照(capture-candidate)。
Verifier 在独立的干净 checkout 上应用候选,并拒绝以下情况(policy.json 中定义的protected_paths、high_risk_paths与候选限额):
- 触碰受保护路径(如
.github/workflows、AGENTS.md、docs/agents、cmd/wkissueagent、Issue Agent 自身的全部 Go 包与测试); - 改动高风险路径(如
internal/config、pkg/cluster、pkg/wkdb、pkg/wkproto、wukongim.toml.example); - 涉及高风险主题(架构、认证授权、集群一致性、并发、数据迁移、依赖、性能、协议、安全、存储格式等);
- 依赖变更、可执行模式变更、符号链接变更、超范围改动、测试后出现意外的文件系统变化,或受信任命令失败。
Verifier 没有模型 key、也没有 Publisher 凭据。候选限额由 policy 明确给定:最多 32 个文件、单文件最大 2 MiB、总改动最大 8 MiB、最多 16 个删除;验证命令为对整个仓库(./cmd/... ./internal/... ./pkg/... ./scripts/... ./docker/...)运行go test -count=1,超时 3600 秒。
6.5 Publisher 发布与状态链
可复用 Engineer 工作流在 Verifier 处结束;始终运行的 Publisher 是顶层受保护 Controller 工作流中的一个 job,这样它的issue-agent-publisherEnvironment secret 可以直接解析,私钥不会传入可复用工作流。发布前 Publisher 会重新读取完整签名状态链、当前 Issue 与动作人权限、Agent 分支、精确父树与 PR,然后只写四样东西:
agent/issue-N分支(通过 expected-head 的createCommitOnBranch创建);- 一个匹配的完整 Draft PR;
agent-state/issue-N状态分支;- 唯一一个 App 拥有的状态评论。
PR 内容必须包含根因、因果路径、变更摘要、受信任命令、风险、不确定性以及Fixes #N。Publisher不执行任何候选代码、永不写main、永不强制采纳外部 head、永不合并、永不直接关闭 Bug。
状态链的持久化设计同样严密:IssueN的持久权威数据是agent-state/issue-N分支上的.issue-agent-state/issue-N.json规范 JSON;每个状态提交必须连续、由配置的 App Bot 作者、且经 GitHub 签名。Issue 中只保留一个可变的 App 拥有状态评论,作为该状态的可修复投影。由于 GitHub 可能对"刚创建完的状态提交"报告歧义错误,Controller 只有在一次独立的重新读取证明"精确预期父提交、规范状态内容、路径、App Bot 身份与 GitHub 签名"全部吻合后才会采纳;任何不匹配都算失败,单纯前移的 ref 或外部写入的 ref 永不采纳。
6.6 过期同步与原子换基
当某个已 Ready 的 Agent PR 落后于main时,Controller不会让 Codex 重解同一 Issue,而是由 Publisher 从其签名源重建完整的有界、线性、App 签名的候选历史,证明当前main没有改动任何最终候选路径,在最新main上重建相同结果树,并通过 expected-head 暂存事务原子换基(atomic swap)Agent ref。新提交再次由 App 作者并 GitHub 签名;换基还会把main围栏(fence)在构建该提交所用的精确父节点上。
任何路径重叠、不支持的树变更、外部 head,或耗尽三次换基预算(policy 中max_base_syncs_per_issue: 3)都会持久地停在needs_human;过期的暂存围栏不改动任何 ref,并从新事实重试。Publisher 从不做语义冲突消解,换基后签名状态记录新 base 与 head、清除既往 Review 权限,并要求独立的 Review Agent 对精确的新 head 做裁决。
6.7 Review Agent 复核回路
对于 Issue Agent 的 PR,Controller只接受由配置的 Review Agent Bot 作者发起的、针对精确最新头的正式CHANGES_REQUESTEDReview 作为修复授权,且只采纳该 Bot 发起的未解决线程;人类 Review 永远是人类权威,不会被转化为自动修复请求。Review 摘要会持久化进 Issue Agent 状态,因此同一次 Review 无法产生无界的修复尝试(policy 中max_review_iterations: 2,即最多两轮有界修复回路)。之后由独立的 Review Agent 裁决,最终由人类合并。可复用工作流内部按签名任务的task.kind选择engineer.md或review.md提示词,两种任务共用同一套安全边界。
6.8 预算、保护路径与策略文件
全部运行时参数集中在.github/issue-agent/policy.json:
{ "schema_version": 2, "default_branch": "main", "publisher_environment": "issue-agent-publisher", "engineer": { "action_sha": "52fe01ec70a42f454c9d2ebd47598f9fd6893d56", "codex_version": "0.146.0", "model": "moonshotai/kimi-k3", "reasoning_effort": "high", "sandbox": "workspace-write", "network_access": true, "ephemeral": true, "wall_time_seconds": 5400, "modify_test_iterations": 3 }, "budgets": { "max_engineer_attempts_per_issue": 3, "max_review_iterations": 2, "max_base_syncs_per_issue": 3, "task_stale_after_seconds": 14400 }, "candidate_limits": { "max_files": 32, "max_file_bytes": 2097152, "max_total_bytes": 8388608, "max_deletions": 16 } }其中task_stale_after_seconds: 14400对应"受保护的四小时终态截止期限":定时 Controller 会终结任何超过该期限仍未产出终态的活动任务。仓库级串行化的五分钟扫描会轮转至多 40 个被跟踪 Issue,因此在成员稳定时,每个活动任务都能在四小时保护期限内被检查到(见 docs/agents/issue-agent.md)。Issue Agent 自身无法修改任何受保护控制路径——这类候选只允许"调查",必须由独立评审的维护者变更才能落地。
7. 历史版本 Bug 报告的处理
Affected version 只会解析为完整仓库提交或不可变 release tag;留空则冻结为授权时刻的精确main。非法或不存在的版本标识会生成具体的信息请求(对应needs-info分诊角色)。Codex 会收到该精确提交,并可使用经过评审的辅助脚本(.github/issue-agent/build-reproduction-binaries.sh)构建历史与当前cmd/wukongim二进制,但绝不编辑历史 checkout。历史诊断始终是咨询性的:发布权威来自干净 Verifier 针对精确修复 base 的测试。如果 Codex 无法从受支持的历史构建取得直接证据,必须停在needs_human。
8. 仓库侧配置:Secrets、Variables 与分支保护
要让整套流水线在某个 GitHub 仓库落地,需要按 docs/agents/issue-agent.md 的 "Repository setup" 完成配置:
- 创建受保护的
issue-agent-publisherEnvironment,不设部署审批门,让已授权的低风险修复能自动开 PR; - Environment secret:
ISSUE_AGENT_APP_PRIVATE_KEY(App 私钥); - Repository secret:
OPENAI_API_KEY(专用 OpenRouter key); - Repository variables:
ISSUE_AGENT_APP_ID、ISSUE_AGENT_APP_INSTALLATION_ID、ISSUE_AGENT_APP_LOGIN,以及REVIEW_AGENT_APP_LOGIN(精确的专用 Review Agent Bot login)。
这些环境变量与 cmd/wkissueagent/main.go 的读取逻辑一一对应:Controller 二进制从GITHUB_REPOSITORY、ISSUE_AGENT_GITHUB_TOKEN、ISSUE_AGENT_APP_ID、ISSUE_AGENT_APP_INSTALLATION_ID、ISSUE_AGENT_REPOSITORY_ID、ISSUE_AGENT_APP_PRIVATE_KEY、REVIEW_AGENT_APP_LOGIN等环境变量构建配置,并支持GITHUB_API_URL覆盖 API 基址。
App 安装被限定在本仓库,权限必须与 internal/infra/issueagentgithub/app_token.go 校验的精确集合一致:
var issueAgentAppPermissions = map[string]string{ "actions": "write", "contents": "write", "issues": "write", "metadata": "read", "pull_requests": "write", }AppTokenMinter使用 RSA 私钥签发 App JWT,通过POST /app/installations/{id}/access_tokens换取短时、仓库限定的安装 token,并严格校验响应中的权限集合、repository_selection、仓库 ID 与 full name 完全匹配,任何不符都会被拒绝。状态机本身定义在 internal/contracts/issueagent/state.go,包含triaging、waiting_for_information、waiting_for_authorization、engineering、draft、reviewing、ready_for_review、needs_human、completed、cancelled、taken_over等规范状态,以及IssueBudget(工程师尝试次数、评审迭代次数、换基次数)与绑定精确任务身份的TaskIdentity。
分支保护必须要求"Review Agent Verdict"检查由专用 App 拥有。Issue Agent 永远不能合并;Review Agent 只允许合并"精确最新头且作者为仓库管理员或组织成员"的已批准 PR,否则 Issue Agent Bot 的 PR 一律等待人工合并。Action 或 Codex 升级属于需要评审的变更:必须同时更新完整 Action SHA、精确 CLI 版本、契约测试与本文档。
9. 本地验证
维护者可以在本地复现 Issue Agent 各层的验证逻辑(GOWORK=off 以避免工作区干扰):
GOWORK=off go test ./internal/contracts/issueagent \ ./internal/usecase/issueagent ./internal/runtime/issueagentverify \ ./internal/infra/issueagentgithub ./internal/access/issueagentcli \ ./internal/app ./cmd/wkissueagent ./scripts -count=1 GOWORK=off go test -tags=integration \ ./internal/runtime/issueagentverify -count=1 go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.9 \ .github/workflows/issue-agent.yml \ .github/workflows/issue-agent-engineer.yml \ .github/workflows/issue-agent-pr-signal.yml契约层自身的责任边界在 internal/contracts/issueagent/FLOW.md 中有清晰定义:它只负责 Issue Agent 各角色间交换的规范 JSON 与绑定这些文档的身份/摘要,不调和生命周期、不调用 GitHub、不校验候选、不运行模型;解码器拒绝未知字段、尾部数据、超大输入、非法身份与无界集合,模型输出中若出现多个 JSON 容器或含括号的散文,则安全地失败关闭。
10. Skill 发布约定:Issue 依赖与 Blocked by
当某个工程技能(engineering skill)指示"发布到 issue tracker"时,应在当前originremote 配置的仓库中创建 GitHub Issue。对于阻塞关系(blocking edges):
- 优先使用GitHub 原生 Issue 依赖(native issue dependencies)表达;
- 若原生依赖不可用,则在被依赖 Issue 的正文中记录
Blocked by: #<number>作为降级约定。
这一约定让技能的产出物(PRD、调研结论、待办项)始终以可追踪、可查询的 Issue 形态沉淀在仓库中,并与 Issue Agent 的调和机制共享同一数据面。
11. 安全边界总结
把 Issue 追踪文档与源码对照后,可以提炼出整套体系的安全设计主线:
- 授权与标签分离:
ready-for-agent只是运行时状态投影,真正的授权来自"当前权限被重新读取的作者 + 精确首行/agent fix"; - 事实与提示分离:事件载荷、评论、模型输出都只是提示;Controller 的一切决策基于重新读取的 GitHub 事实,持久权威是 App 签名、连续、可独立验证的状态链;
- 咨询与权威分离:Codex 的工程师结论(含测试声明)只是咨询,只有干净 Verifier 的低风险通过证据才能进入 Publisher 计划;
- 能力与执行分离:Codex 无任何凭据与发布权限,Publisher 无模型 key 且不执行候选代码,Verifier 两者皆无;
- 人类始终在场:Issue Agent 只能开 Draft PR 并停在
Fixes #N,Review Agent 有界复核至多两轮,合并永远由人类或满足精确条件的 Review Agent 完成。
这套约定保证了 WuKongIM 的 Bug 提报、授权、自动化修复与人工评审各自职责清晰,既能让低风险的确定性修复以接近人工效率的方式闭环,又不会让任何一条自动化路径越权触碰main或关键配置。
- 即时通讯
- 后端
【免费下载链接】WuKongIM
More than just IM 不只是即时通讯(IM)
相关推荐
ruflo 的 GitHub Issue 蜂群协调实战:从 Issue 到多 Agent 智能任务的自动化分解与进度追踪
ruflo 的 GitHub Issue 蜂群协调实战:从 Issue 到多 Agent 智能任务的自动化分解与进度追踪 导读 本文将完整讲解 ruflo 项目
人工智能AI Agent多智能体Agent 编排Agent 记忆工具调用代码智能体MCP 服务AI 评测bitsandbytes Issue 自动派发指南:从 Issue 分析到 Agent 修复任务的全流程实战
bitsandbytes Issue 自动派发指南:从 Issue 分析到 Agent 修复任务的全流程实战 导读 本文完整解读 bitsandbytes 仓库
人工智能大模型模型量化模型优化PyTorch fix-issue Skill:让 AI Agent 自动定位并修复 GitHub Issue 的完整工作流
PyTorch fix issue Skill:让 AI Agent 自动定位并修复 GitHub Issue 的完整工作流 PyTorch 仓库在 .clau
人工智能机器学习深度学习分布式训练模型编译
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考