Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/auto-fix-limit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: auto-fix-limit
# agent 修复循环上限执法(ADR-0040,P2-8 .github#93):
# 小时级扫描受管仓 agent open PR 的 gate 失败计数(真源=Checks API,崩溃续接),
# 达上限(policy/automation-limits.yaml,默认 3)→ 撤 auto-merge + 关 PR + 开说明 issue;
# 熔断变量置位时每轮撤全部 open PR 的 auto-merge(硬停机器执法,旁路窗口 ≤1h)。
# 脚本细节/注入通道见 governance/auto-fix-limit.sh 头注。
on:
schedule:
- cron: "18 * * * *" # 每小时 :18(避开整点 governance-drift 高峰)
workflow_dispatch:
# 注入入口(T1 测试/聚焦扫描):空=走 policy 真源,不留常开旁路
inputs:
max_attempts:
description: "auto-fix 上限覆盖(空=policy 值)"
required: false
default: ""
check_name:
description: "计数的 check 名覆盖(空=gate)"
required: false
default: ""
repos:
description: "扫描仓覆盖(逗号表,空=REPOS.yaml 全量 active)"
required: false
default: ""
all_prs:
description: "扫描全部 open PR(true=不限 agent 作者;空=仅 agent+opt-in)"
required: false
default: ""
dry_run:
description: "1=只报告不执行写操作(T1 预检)"
required: false
default: ""

permissions: {}

# 串行化:关 PR/开 issue 的"查重→写"非原子,并发运行会重复开 issue(同 governance-drift 设计)
concurrency:
group: auto-fix-limit
cancel-in-progress: false

jobs:
scan:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: 扫描并执法(超限关 PR;exit 1=有超限 2=基础设施故障)
env:
GH_TOKEN: ${{ secrets.GOVERNANCE_TOKEN }}
AUTOFIX_MAX_ATTEMPTS: ${{ inputs.max_attempts }}
AUTOFIX_CHECK_NAME: ${{ inputs.check_name }}
AUTOFIX_REPOS: ${{ inputs.repos }}
AUTOFIX_ALL_PRS: ${{ inputs.all_prs }}
AUTOFIX_DRY_RUN: ${{ inputs.dry_run }}
run: bash governance/auto-fix-limit.sh
58 changes: 58 additions & 0 deletions .github/workflows/cost-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: cost-check
# 额度/成本熔断(ADR-0040,P2-8 .github#93):
# 6h 周期拉取 /orgs/{org}/settings/billing/usage 当月 Actions 分钟 vs
# policy/automation-limits.yaml 声明预算——≥80% 告警 issue;≥100% 置 org 变量
# AUTO_MERGE_DISABLED + 撤全部 open PR auto-merge + P0 issue。复位仅人工(变量 PATCH/DELETE
# + P0 留评论),脚本观察到复位后自动关 P0。脚本细节/注入通道见 governance/cost-check.sh 头注。
on:
schedule:
- cron: "42 */6 * * *" # 每 6h :42(避开整点 governance-drift 与 :18 auto-fix-limit)
workflow_dispatch:
# 注入入口(T2 注入式测试:79%/85%/100% 全场景不依赖真实超支):空=真实 API/真源
inputs:
usage_minutes_override:
Comment on lines +10 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

4. Dispatch grants org-wide mutations 🐞 Bug ⛨ Security

Any repository writer who can manually dispatch these workflows can supply hard-stop or all-PR
inputs that execute with the organization-admin GOVERNANCE_TOKEN. For example,
usage_minutes_override can trip the organization breaker, while all_prs=true and
max_attempts=0 can close every listed open PR without requiring dry-run.
Agent Prompt
## Issue description
Manual dispatch inputs permit repository writers to invoke destructive organization-wide actions with an admin secret.

## Issue Context
GitHub permits users with repository write access to trigger `workflow_dispatch`; dry-run defaults to disabled and the supplied inputs directly control enforcement.

## Fix Focus Areas
- .github/workflows/cost-check.yml[10-32]
- .github/workflows/cost-check.yml[50-58]
- .github/workflows/auto-fix-limit.yml[10-32]
- .github/workflows/auto-fix-limit.yml[51-59]

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

description: "当月 Actions 分钟用量覆盖(数值;空=billing API 真实值)"
required: false
default: ""
quota_minutes_override:
description: "月预算分钟覆盖(空=policy 值)"
required: false
default: ""
llm_tokens_used_override:
description: "LLM token 用量覆盖(pending 数据源的注入测试通道)"
required: false
default: ""
llm_tokens_quota_override:
description: "LLM token 月预算覆盖(空=policy 值)"
required: false
default: ""
dry_run:
description: "1=只报告不执行写操作(含不置熔断变量——注入预检用)"
required: false
default: ""

permissions: {}

concurrency:
group: cost-check
cancel-in-progress: false

jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: 用量检查与熔断(exit 1=触发告警/熔断 2=基础设施故障)
env:
GH_TOKEN: ${{ secrets.GOVERNANCE_TOKEN }}
COST_USAGE_MINUTES_OVERRIDE: ${{ inputs.usage_minutes_override }}
COST_QUOTA_MINUTES_OVERRIDE: ${{ inputs.quota_minutes_override }}
COST_LLM_TOKENS_USED_OVERRIDE: ${{ inputs.llm_tokens_used_override }}
COST_LLM_TOKENS_QUOTA_OVERRIDE: ${{ inputs.llm_tokens_quota_override }}
COST_DRY_RUN: ${{ inputs.dry_run }}
run: bash governance/cost-check.sh
6 changes: 4 additions & 2 deletions .github/workflows/gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ jobs:
EOF
- name: 脚本语法检查
run: |
bash -n governance/apply.sh && bash -n governance/drift-check.sh && bash -n scripts/new-repo-init.sh && bash -n scripts/gh-app-token.sh
# ADR-0040:生存护栏脚本纳入同一语法门(新增脚本不登记=语法检查盲区)
bash -n governance/apply.sh && bash -n governance/drift-check.sh && bash -n scripts/new-repo-init.sh && bash -n scripts/gh-app-token.sh \
&& bash -n governance/auto-fix-limit.sh && bash -n governance/cost-check.sh
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
echo "OK scripts"
- name: REPOS.yaml 引用自检(无重名仓)
run: |
Expand Down Expand Up @@ -169,4 +171,4 @@ jobs:
if [[ $MISSING -eq 0 ]]; then
echo "OK adr-required: $( { echo "$PR_TITLE"; echo "$PR_BODY"; } | grep -oE "$ADR_RE" | sort -u | tr '\n' ' ')(存在性已验;实体性后验:drift-check §10)"
fi
exit $MISSING
exit $MISSING
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ AI agent 进入本仓的工作契约(索引型,CG-1;细节按需读引用
- agent 写仓库身份 = GitHub App `cloudbrid-agent`(AG-1);令牌经 scripts/gh-app-token.sh,单仓作用域、1h 过期
- 本仓只读治理声明;ADR 与注册条目落盘 agent-registry(REPOS.yaml L1)
- 不引入新第三方 Action:白名单见 expected-state.json#actions_policy(CI-2)
- 无人值守护栏(ADR-0040,跨仓生效):(a) 每次任务派发与 `gh pr merge --auto` 前,必须检查 org 变量 `AUTO_MERGE_DISABLED`(`gh api /orgs/Cloudbird-Software/actions/variables/AUTO_MERGE_DISABLED --jq .value`,404=未置位)——置位即停一切派发与 automerge,禁止任何绕过尝试;(b) 同一 PR 的修红重试 ≤ policy/automation-limits.yaml `auto_fix.max_attempts`(默认 3),达上限即停手(auto-fix-limit workflow 会关 PR + 开 issue);(c) 不得 reopen 带 `auto-fix-limit-exhausted` 标签的 PR;计数真源 = Checks API(commit 元数据),删标签/重开不重置计数;(d) 派发前确认 .github 仓无未决 `cost-infra`/`cost-circuit-breaker` issue(用量不可知时同样停)

## 常用命令

- 校验本仓声明:`.github/workflows/gate.yml`(本地等价:yaml/json 解析 + `bash -n` 各脚本)
- 漂移检测:`GH_TOKEN=<org admin> bash governance/drift-check.sh`(每日 CI 自动跑)
- 修复循环上限执法:`GH_TOKEN=<org admin> bash governance/auto-fix-limit.sh`(小时级 CI 自动跑;`AUTOFIX_DRY_RUN=1` 只报告)
- 成本熔断检查:`GH_TOKEN=<org admin> bash governance/cost-check.sh`(6h CI 自动跑;`COST_USAGE_MINUTES_OVERRIDE=<n>` 注入测试)
- 漂移修复:`GH_TOKEN=<org admin> bash governance/apply.sh`(幂等;失败 loud 退出)
- 新仓初始化:`bash scripts/new-repo-init.sh <name>`(失败 loud 退出)

Expand All @@ -25,6 +28,7 @@ AI agent 进入本仓的工作契约(索引型,CG-1;细节按需读引用
| 期望状态(漂移真源) | governance/expected-state.json |
| 语言/依赖政策 | governance/policy/languages.yaml |
| 测试政策 | governance/policy/testing.yaml |
| 无人值守护栏阈值(auto-fix 上限/成本熔断,ADR-0040) | governance/policy/automation-limits.yaml |
| agent 标准 schema | standards/agent/*.schema.yaml |
| 自动化规范(CI 链路 / bot 反馈通道,ADR-0031/0032) | standards/automation/ |
| 原型 profiles / 注册条目 | Cloudbird-Software/agent-registry |
| 原型 profiles / 注册条目 | Cloudbird-Software/agent-registry |
Loading