Skip to content

feat(governance): §12 待接入计数汇总行 + IR-0002 (a)/(b) 分类器自测入 CI(IR-0002 #143 收口,ADR-0034/0058) - #228

Merged
randypanding merged 1 commit into
mainfrom
ir0002-closeout
Aug 21, 2026
Merged

feat(governance): §12 待接入计数汇总行 + IR-0002 (a)/(b) 分类器自测入 CI(IR-0002 #143 收口,ADR-0034/0058)#228
randypanding merged 1 commit into
mainfrom
ir0002-closeout

Conversation

@randypanding

@randypanding randypanding commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Card: #143

动机

IR-0002(#143)核心实现已由 #175/#178 落地并在生产 drift run 验证(8 仓 §12 误报清零、agent-platform 正确归 (a) 待接入)。收口缺口有二:

  1. spec AC-3 要求"输出包含『待接入』计数的信息行"——现状只有逐仓 OK 行,无汇总计数;
  2. 卡面验收证据要求"人为构造 (b) 形态的实测记录(红→绿)"——(b) 检出灵敏度(INV-4)目前只有生产旁证,无机器可回归的构造测试。

变更清单

  • governance/drift-check.sh §12:缺失形态判定抽取为 s12_classify()(标记对包裹,行为等价重构);逐仓 REPO_PENDING + 全仓 S12_PENDING 计数;循环后新增汇总信息行(有待接入打 INFO 含计数;零待接入打 OK——"本节确实跑过"成为审计事实)
  • governance/tests/test-ir0002.sh(新增):按标记对从 drift-check.sh 提取被测函数(不复制实现,防"测试测影子"),fixture 断言 5 形态:(a)-1 生效后无 PR 活动 / (a)-2 degenerate 采样 / (b) 生效后 PR head 缺失→裸奔报警 / (b)-边界 生效前 PR 不构成 (b) 证据 / fail-closed 查询失败
  • .github/workflows/gate.yml + Makefile gates-pr:挂 governance/tests/test-*.sh(目录空=测试面丢失,fail-closed)

AC 映射(#143 可观察变化)

测试方法

  • 本地:bash governance/tests/test-ir0002.sh → 5/5 PASS(含 (b) 报警断言);bash -n 全治理脚本过;gate.yml yaml 解析过
  • CI:gate.yml 新步骤跑同一测试(runner 预装 jq)

风险与回滚

  • 分类逻辑为行为等价抽取(判据/文案/顺序不变),风险集中在函数化重构本身;自测即为其回归网
  • 回退 = 还原 drift-check.sh §12 段与 gate.yml/Makefile 三处(纯检测逻辑,无状态迁移)

ADR-0034(§12 语义)· ADR-0058((a) 泛化与豁免勘误背景)

Summary by CodeRabbit

  • 新增功能

    • 增加治理规则自测流程,自动执行相关测试并在缺少测试或测试失败时阻止通过。
    • 优化漂移检测结果分类,区分查询失败、待接入状态及缺失必要检查等情况。
    • 新增待接入状态及汇总信息,提升检测结果的可见性。
  • 测试

    • 增加多种治理场景的自动化验证,覆盖无活动、检查缺失、边界条件及查询失败等情况。

… 收口,ADR-0034/0058)

- s12_classify() 抽取为标记对函数(行为等价重构),governance/tests/test-ir0002.sh
  按标记提取做 fixture 自测:(a) 归待接入 / (b) 裸奔报警不降级 / 生效前活动
  边界 / fail-closed 语义,5 断言全过
- §12 汇总信息行:待接入计数可见(spec AC-3),零待接入也打 OK 行(审计事实)
- gate.yml + Makefile gates-pr 挂 governance/tests(目录空=测试面丢失 fail-closed)
Copilot AI lite review requested due to automatic review settings August 21, 2026 17:13
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 00fcdb1c-81a1-4ae6-bd73-f4001d1da376

📥 Commits

Reviewing files that changed from the base of the PR and between c02f69f and d89b4c4.

📒 Files selected for processing (4)
  • .github/workflows/gate.yml
  • Makefile
  • governance/drift-check.sh
  • governance/tests/test-ir0002.sh

📝 Walkthrough

Walkthrough

Changes

IR-0002 治理检查

Layer / File(s) Summary
分类 required check 缺失状态
governance/drift-check.sh
新增 s12_classify,区分查询失败、IR-0002(a) 待接入和 IR-0002(b) 活跃 PR 缺失 gate,并汇总待接入数量。
验证 IR-0002 分类场景
governance/tests/test-ir0002.sh
新增五类 fixture 测试,校验分类结果、返回码、漂移计数和关键输出。
接入治理自测门禁
.github/workflows/gate.yml, Makefile
本地和 CI 门禁自动执行 governance/tests/test-*.sh。测试脚本为空时执行失败。

Suggested labels: security, feature

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ir0002-closeout

Comment @coderabbitai help to get the list of available commands.

@randypanding
randypanding merged commit b0e87f3 into main Aug 21, 2026
11 of 12 checks passed
@randypanding
randypanding deleted the ir0002-closeout branch August 21, 2026 17:14
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add §12 pending summary line and CI fixtures for IR-0002 (a)/(b) classifier

✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Refactor §12 missing-shape logic into s12_classify() and surface per-repo + global pending
 counts.
• Add fixture-based self-test extracting the real classifier to prevent “shadow tests”.
• Wire governance self-tests into CI and local make gates-pr with fail-closed behavior.
Diagram

graph TD
  GH["gate.yml"] --> Run["Run governance tests"] --> T1["test-ir0002.sh"] --> Extract["Extract s12_classify"] --> S12["s12_classify()"] --> Drift["drift/ok output"]
  MK["Makefile gates-pr"] --> Run
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Move classifier into a sourced library file
  • ➕ Avoids awk/marker extraction and eval in tests
  • ➕ Allows other scripts/tests to reuse classifier directly
  • ➖ Requires file split and slightly more repo structure changes
  • ➖ May be seen as over-architecting for a single function
2. Use a shell test framework (bats-core / shunit2)
  • ➕ More structured assertions/output and easier extension of fixtures
  • ➕ Better failure reporting for CI
  • ➖ Adds a new dependency/tooling surface
  • ➖ May conflict with repo preference for pure bash + jq
3. Promote classifier test to an end-to-end drift-check fixture run
  • ➕ Validates integration wiring (counters + summary line) in addition to classifier
  • ➕ Less coupling to function extraction details
  • ➖ Harder to keep hermetic (needs more stubbing of gh/jq inputs)
  • ➖ More brittle and slower than unit-style function fixtures

Recommendation: Current approach is a good closeout: keeping the classifier in drift-check.sh avoids churn, while marker-based extraction ensures the test exercises the real implementation (preventing divergence). If the classifier grows further or is reused elsewhere, consider the sourced-library alternative to remove eval/marker coupling.

Files changed (4) +155 / -15

Enhancement (1) +51 / -15
drift-check.shExtract §12 classifier and add pending-count summary line +51/-15

Extract §12 classifier and add pending-count summary line

• Introduces 's12_classify()' (marker-delimited for test extraction) encapsulating IR-0002 §12 (a)/(b)/fail-closed classification. Tracks per-repo pending required checks and emits a new §12 summary info/OK line reporting total pending count.

governance/drift-check.sh

Tests (1) +90 / -0
test-ir0002.shAdd hermetic fixture tests for IR-0002 §12 (a)/(b) classifier +90/-0

Add hermetic fixture tests for IR-0002 §12 (a)/(b) classifier

• Adds a bash+jq test that extracts 's12_classify()' from drift-check.sh via marker pairs and runs 5 fixtures covering (a)-1, (a)-2, (b), (b) boundary (pre-effective), and fail-closed. Asserts rc and key output strings (e.g., “裸奔窗口”) to preserve detection sensitivity.

governance/tests/test-ir0002.sh

Other (2) +14 / -0
gate.ymlRun governance/tests in CI with fail-closed discovery +12/-0

Run governance/tests in CI with fail-closed discovery

• Adds a CI step that discovers 'governance/tests/test-*.sh' and runs them. Fails the workflow if the directory has no matching tests to prevent silent loss of coverage.

.github/workflows/gate.yml

MakefileRun governance self-tests in local gates-pr +2/-0

Run governance self-tests in local gates-pr

• Extends 'make gates-pr' to execute 'governance/tests/test-*.sh' locally (noting jq requirement). Aligns local preflight with the CI gate semantics.

Makefile

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

本 PR 收口 IR-0002 #143 的剩余验收项:为 drift-check.sh 的 §12 “required check 活体存在性”输出补上“待接入”计数汇总行(AC-3),并将 (a)/(b) 分类器通过标记对提取纳入可回归的 fixture 自测,同时把该自测接入 gate CI 与本地 gates-pr。

Changes:

  • governance/drift-check.sh 中抽取 §12 缺失形态判定为 s12_classify(),并为每仓与全仓累计 “(a) 待接入”计数,循环结束后输出 §12 汇总信息行。
  • 新增 governance/tests/test-ir0002.sh,通过从 drift-check.sh 提取被测函数进行 5 类形态断言(含 (b) 构造用例与 fail-closed)。
  • 更新 .github/workflows/gate.ymlMakefile,将 governance/tests/test-*.sh 自测接入 CI 与本地 make gates-pr

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
Makefile 本地 gates-pr 新增运行 governance/tests/test-*.sh 的自测步骤。
governance/tests/test-ir0002.sh 新增 IR-0002 §12 (a)/(b) 分类器 fixture 自测脚本(从 drift-check 标记对提取实现)。
governance/drift-check.sh §12 抽取 s12_classify() 并加入待接入计数与汇总信息行输出。
.github/workflows/gate.yml CI 中新增治理脚本自测步骤,自动发现并运行 governance/tests/test-*.sh(空目录 fail-closed)。

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Makefile
Comment on lines +27 to +28
@for t in governance/tests/test-*.sh; do bash "$$t"; done \
&& echo "OK 治理自测(governance/tests;需 jq)"
Comment thread governance/drift-check.sh
Comment on lines +604 to +610
rc=0
s12_classify "$r" "$ctx" "$QUERY_FAIL" "${HAS_PR_ACTIVITY:-1}" "$PRS_RECENT" "$ORG_GATE_EFFECTIVE" "$N_CONCL" || rc=$?
case $rc in
0) REPO_PENDING=$((REPO_PENDING+1)); S12_PENDING=$((S12_PENDING+1)) ;;
1) LIVE_MISS=1 ;;
2) : ;;
esac
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Fail-closed still prints OK 🐞 Bug ≡ Correctness
Description
在 §12 中,当 s12_classify() 因 check-runs 查询失败走 fail-closed(返回 2 并输出 DRIFT)或本节出现其它 DRIFT
时,调用方仍可能不标记缺失/不可验证状态并在 S12_PENDING==0LIVE_MISS==0 的条件下输出“全部齐备/显式 SKIP”或“required check 齐备”的
OK 文案,从而与同节产生的 DRIFT 同时出现并在审计证据上形成自相矛盾的“全绿”结论。该误导性汇总会让读者误判 §12 在存在漂移时仍然通过。
Code

governance/drift-check.sh[R605-610]

+      s12_classify "$r" "$ctx" "$QUERY_FAIL" "${HAS_PR_ACTIVITY:-1}" "$PRS_RECENT" "$ORG_GATE_EFFECTIVE" "$N_CONCL" || rc=$?
+      case $rc in
+        0) REPO_PENDING=$((REPO_PENDING+1)); S12_PENDING=$((S12_PENDING+1)) ;;
+        1) LIVE_MISS=1 ;;
+        2) : ;;
+      esac
Evidence
证据显示 s12_classify()QUERY_FAIL==1 时会调用 drift(...)return 2(fail-closed),且在 (b) 等情形也会调用
drift() 增加漂移计数;但调用方在处理 rc=2 时仅执行空操作 :,没有对该仓设置任何会阻止通过结论的状态标记,因此循环结束后仍可能满足 LIVE_MISS==0
并打印“required check 齐备”的仓级 OK 行。同时,§12 末尾的汇总行在 S12_PENDING==0 时走 else 分支无条件输出“全部受管仓要么齐备要么显式 SKIP”的
OK 文案;由于同一节内已明确可能产生 DRIFT,这个无条件断言在出现 §12 DRIFT 时不成立,从而造成 DRIFT 与 OK 并存的矛盾日志与误导性审计结论。

governance/drift-check.sh[512-515]
governance/drift-check.sh[603-616]
governance/drift-check.sh[510-531]
governance/drift-check.sh[621-625]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
§12 的输出逻辑在出现 DRIFT(尤其是 `s12_classify()` fail-closed 返回 `rc=2` 并打印 DRIFT)时,仍可能继续输出“required check 齐备”的仓级 OK 行,以及在 `S12_PENDING==0` 时无条件输出“全部受管仓要么齐备要么显式 SKIP”的 §12 汇总 OK 行,导致同一节中同时出现 DRIFT 与“全绿/齐备”的结论性 OK 文案,语义冲突并误导审计读者。

## Issue Context
- `drift-check.sh` 的输出文本会被当作审计/定位信号使用;在 fail-closed 或本节已产生 DRIFT 的情况下,应避免任何会被误读为“已验证通过/全部齐备”的 OK 汇总。
- §12 的 DRIFT 可能来自 `s12_classify()` 的 (b) 场景与 fail-closed 查询失败,也可能来自本节其它 fail-closed 分支;因此“零待接入/全部齐备”的 OK 汇总需要受“本节是否产生 DRIFT/是否存在不可验证状态”的约束。

## Fix Focus Areas
- governance/drift-check.sh[605-616]
- governance/drift-check.sh[621-625]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 16 rules
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 6/18, lines 170/200; both must reach the floor). Router rationale: This changes governance runtime logic, aggregation semantics, fail-closed classification, and two CI entry points, with a substantial new fixture harness—multiple independent shell/CI paths create a meaningful chance of subtle defects a redundant pass could catch.

Grey Divider

Tip of the day
💡 Did you know, you can tweak Display preferences with a live preview to see your comment before it ships

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread governance/drift-check.sh
Comment on lines +605 to +610
s12_classify "$r" "$ctx" "$QUERY_FAIL" "${HAS_PR_ACTIVITY:-1}" "$PRS_RECENT" "$ORG_GATE_EFFECTIVE" "$N_CONCL" || rc=$?
case $rc in
0) REPO_PENDING=$((REPO_PENDING+1)); S12_PENDING=$((S12_PENDING+1)) ;;
1) LIVE_MISS=1 ;;
2) : ;;
esac

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Fail-closed still prints ok 🐞 Bug ≡ Correctness

在 §12 中,当 s12_classify() 因 check-runs 查询失败走 fail-closed(返回 2 并输出 DRIFT)或本节出现其它 DRIFT
时,调用方仍可能不标记缺失/不可验证状态并在 S12_PENDING==0LIVE_MISS==0 的条件下输出“全部齐备/显式 SKIP”或“required check 齐备”的
OK 文案,从而与同节产生的 DRIFT 同时出现并在审计证据上形成自相矛盾的“全绿”结论。该误导性汇总会让读者误判 §12 在存在漂移时仍然通过。
Agent Prompt
## Issue description
§12 的输出逻辑在出现 DRIFT(尤其是 `s12_classify()` fail-closed 返回 `rc=2` 并打印 DRIFT)时,仍可能继续输出“required check 齐备”的仓级 OK 行,以及在 `S12_PENDING==0` 时无条件输出“全部受管仓要么齐备要么显式 SKIP”的 §12 汇总 OK 行,导致同一节中同时出现 DRIFT 与“全绿/齐备”的结论性 OK 文案,语义冲突并误导审计读者。

## Issue Context
- `drift-check.sh` 的输出文本会被当作审计/定位信号使用;在 fail-closed 或本节已产生 DRIFT 的情况下,应避免任何会被误读为“已验证通过/全部齐备”的 OK 汇总。
- §12 的 DRIFT 可能来自 `s12_classify()` 的 (b) 场景与 fail-closed 查询失败,也可能来自本节其它 fail-closed 分支;因此“零待接入/全部齐备”的 OK 汇总需要受“本节是否产生 DRIFT/是否存在不可验证状态”的约束。

## Fix Focus Areas
- governance/drift-check.sh[605-616]
- governance/drift-check.sh[621-625]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants