From 487732be93b1882d5f2166982629d97c782d848d Mon Sep 17 00:00:00 2001 From: randypanding Date: Sat, 29 Aug 2026 04:43:04 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20T6=20=E5=8F=AF=E8=BE=BE=E6=80=A7?= =?UTF-8?q?=E8=A1=A5=E6=B4=9E=E2=80=94=E2=80=94guard=20=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=20owner=E2=88=AAagent=20+=20=E4=B8=89=E5=85=83=E7=BB=84=20run?= =?UTF-8?q?=5Fid=20=E6=A0=87=E7=AD=BE=E8=B7=AF=E5=BE=84=E5=9B=9E=E9=80=80?= =?UTF-8?q?=EF=BC=88ADR-0085=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit W4-C1 上线的 T6(redteam→wave-planned)自部署即不可达(IR-0006 W1 实走发现): - workflow_run 未注册触发;repository_dispatch 无法定位 issue(github.event.issue 空) 且 etype 白名单永不匹配;label 路径被 sender_role=='agent' guard 拒绝 (唯一 agent 身份=cloudbrid-agent App,无任何组件替 PM 打该标签)。 - 即便 App 打标签,check_triple_survived 的 run_id 只认 dispatch 载荷→标签路径 必然 DENIED"缺少审计 run ID"。 修复(证据闸门语义不变,fail-closed 不变): - transitions.yaml T6 guard 对齐 T1/T5/T7-T9 的 owner∪agent——PLAYBOOK §3 "打 adversary:survived 标签→T6"的 PM 主路径恢复可用; - conductor 路由 check_triple_survived:run_id 缺载荷时从本卡 survived 评论机械提取 (须含 verdict=survived 且带 run_id 键,与跨卡复用检查同源同则)。 三元组其余两项(卡 ID、specVersion)与跨卡复用检查不动。conductor.yml 同字节部署面(.github+8 产品仓+template-service)另行同步跟进。 Refs: ADR-0085(PM 优先范式收口/状态机补洞先例)、ADR-0079(T6 原设计) --- .github/workflows/conductor.yml | 15 +++++++++++++++ governance/transitions.yaml | 8 +++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/conductor.yml b/.github/workflows/conductor.yml index 054e33f..3d43768 100644 --- a/.github/workflows/conductor.yml +++ b/.github/workflows/conductor.yml @@ -389,6 +389,21 @@ jobs: if payload: run_id = (payload.get("client_payload") or {}).get("run_id") or payload.get("run_id") verdict_from_dispatch = (payload.get("client_payload") or {}).get("verdict") + if not run_id: + # 标签路径补件(ADR-0085,IR-0006 W1 实走发现 2026-08-29): + # label:state:wave-planned 事件无 dispatch 载荷——run_id 从本卡 + # survived 评论机械提取(评论须含 verdict=survived/adversary:survived + # 且带 run_id 键,与下方跨卡复用检查同源同则);提取不到仍 + # fail-closed 拒绝("缺少审计 run ID") + st_c2, cs = api(E["APP_TOKEN"], f"/repos/{REPO}/issues/{issue_number}/comments") + if st_c2 == 200: + for c in cs or []: + cb = c.get("body", "") + if "adversary:survived" in cb or "verdict=survived" in cb: + m_run0 = re.search(r"run[_-]?id[=:]\s*([A-Za-z0-9_\-]+)", cb, re.I) + if m_run0: + run_id = m_run0.group(1) + break # 三元组完整性检查 if not spec_version: return False, "缺少 specVersion(issue body 未含 specVersion 字段)", None diff --git a/governance/transitions.yaml b/governance/transitions.yaml index a9885b2..50a9c0d 100644 --- a/governance/transitions.yaml +++ b/governance/transitions.yaml @@ -78,7 +78,13 @@ transitions: event: label:state:wave-planned to_state: wave-planned action: noop - guard: "sender_role == 'agent' and 'adversary:survived' in label_set" + # guard 补洞(ADR-0085,IR-0006 W1 实走发现 2026-08-29):原 sender_role=='agent' + # 意图=机器驱动,但 agent 自动触发面自 W4-C1 上线即未接线(workflow_run 未注册 + # 触发、repository_dispatch 无法定位 issue、标签路径无 dispatch 载荷)——T6 对 + # 全部注册事件不可达,PLAYBOOK §3"打 adversary:survived 标签→T6"的 PM 主路径 + # 被 owner 身份拒绝。对齐 T1/T5/T7-T9 的 owner∪agent;证据闸门不变:三元组 + # (卡 ID+specVersion+审计 run ID)仍由 conductor 机械校验,fail-closed。 + guard: "sender_role in ['owner', 'agent'] and 'adversary:survived' in label_set" triple_check: # conductor 在转移前校验三元组 survived 记录 card_id: issue # 卡 ID 键 = 当前 issue number spec_version: spec # specVersion 键 = spec 文件版本(SHA 或 semver)