-
Notifications
You must be signed in to change notification settings - Fork 0
feat(entry): 统一入口协议块+conductor 仲裁转介+factory-floor 板+dashboard 账本(W1-C3 #166,ADR-0055) #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f72d952
7e9f461
fcd4e81
0c5e335
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,46 @@ | ||||||||||||||||||||||||||||||||||||||||
| name: board-sync | ||||||||||||||||||||||||||||||||||||||||
| # 手动/演习驱动 factory-floor 板同步 + dashboard 账本刷新(W1-C3 #166 / ADR-0055 决策 10)。 | ||||||||||||||||||||||||||||||||||||||||
| # **本工作流刻意不带 schedule**:日常每 15min cron 由 butler-ledger.yml(ADR-0057, | ||||||||||||||||||||||||||||||||||||||||
| # 唤醒矩阵行 2)统一驱动 governance/board-sync.py 与 governance/dashboard-update.py—— | ||||||||||||||||||||||||||||||||||||||||
| # 若两处 cron 并存会对同一投影双写竞态;本 dispatch 面 = 演习/手动补偿通道。 | ||||||||||||||||||||||||||||||||||||||||
| # concurrency 组与 butler-ledger 同名(GitHub concurrency 组按仓全局生效):手动面 | ||||||||||||||||||||||||||||||||||||||||
| # 与 cron 面互斥串行,杜绝并发写同一 Project/issue。 | ||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||
| workflow_dispatch: {} | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||
| contents: read # checkout 本仓两脚本;写操作全走 GOVERNANCE_TOKEN(非 GITHUB_TOKEN) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| concurrency: | ||||||||||||||||||||||||||||||||||||||||
| group: butler-ledger # 与 butler-ledger.yml 共组(ADR-0055 决策 10——防双写竞态) | ||||||||||||||||||||||||||||||||||||||||
| cancel-in-progress: false | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||
| sync: | ||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||
| timeout-minutes: 10 # GraphQL 投影 + SLI 采集的硬上限(宪法 workflow 规范) | ||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||
| persist-credentials: false | ||||||||||||||||||||||||||||||||||||||||
| # GOVERNANCE_TOKEN(org admin PAT):board-sync 需 org project 权限(GraphQL), | ||||||||||||||||||||||||||||||||||||||||
| # dashboard-update 需 .github 仓 issues 写——GITHUB_TOKEN 两者皆无,不分开铸币 | ||||||||||||||||||||||||||||||||||||||||
| - name: board-sync + dashboard 刷新(fail-closed) | ||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||
| GH_TOKEN: ${{ secrets.GOVERNANCE_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||
| BUTLER_TRIGGER: ${{ github.event_name }} | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+28
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
第 32 行把 org admin PAT 注入到可由 但注释没有说明为何不用 GitHub App 令牌。 安全姿态差异是实质的:
这不是可直接利用的漏洞,属安全姿态降级与治理声明不一致。请确认两点:GitHub App 是否确实无法获得 org Project(v2) 写权限;若确实无法,请在 ADR-0055 中记录该例外,并把 本条依据学习:“agent 写仓库身份 = GitHub App 🤖 Prompt for AI AgentsSource: Learnings |
||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||
| set -uo pipefail | ||||||||||||||||||||||||||||||||||||||||
| source governance/butler-audit.sh | ||||||||||||||||||||||||||||||||||||||||
| if ! python3 governance/board-sync.py; then | ||||||||||||||||||||||||||||||||||||||||
| audit_emit board-sync manual infra-fail '{"rc":"nonzero"}' || true | ||||||||||||||||||||||||||||||||||||||||
| echo "::error::board-sync.py 失败(fail-closed——投影失败不得静默,ADR-0055)" >&2 | ||||||||||||||||||||||||||||||||||||||||
| exit 2 | ||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+34
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
第 35 行是 后续链条:第 38 行的
🛠️ 建议修复 run: |
set -uo pipefail
- source governance/butler-audit.sh
+ if ! source governance/butler-audit.sh || ! command -v audit_emit >/dev/null; then
+ echo "::error::governance/butler-audit.sh 加载失败或未定义 audit_emit(审计失明——fail-closed)" >&2
+ exit 2
+ fi
if ! python3 governance/board-sync.py; then📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||
| if ! python3 governance/dashboard-update.py; then | ||||||||||||||||||||||||||||||||||||||||
| audit_emit dashboard-update manual infra-fail '{"rc":"nonzero"}' || true | ||||||||||||||||||||||||||||||||||||||||
| echo "::error::dashboard-update.py 失败(fail-closed——账本刷新失败不得静默)" >&2 | ||||||||||||||||||||||||||||||||||||||||
| exit 2 | ||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,20 +2,27 @@ name: conductor | |
| # 状态机路由器(IR-0001 W0-C3 / ADR-0049)。W0 事件面=本仓(issues.labeled + | ||
| # issue_comment);跨仓扩展随产品仓接入。全部状态标签写操作以 cloudbrid-agent | ||
| # App 令牌执行(INV-02:GITHUB_TOKEN 身份不持有状态写权)。 | ||
| # W1-C3(ADR-0055 决策 6):写入类 front-desk 命令(/claim /release)前置转介 | ||
| # arbiter 裁决(宪法 §11 唤醒矩阵事件行"仲裁请求处理(/claim 等,转 arbiter)"); | ||
| # 仲裁是叠加授权层,transitions.yaml 转移表语义不变。三态:0=allow 继续原动作、 | ||
| # 1=deny 审计 no-op(对齐 silent-drop)、2=infra run 红灯 fail-closed 不放行。 | ||
| on: | ||
| issues: | ||
| types: [labeled] | ||
| issue_comment: | ||
| types: [created] | ||
|
|
||
| # INV-09:每 issue 一个 concurrency group、cancel-in-progress=false——重复投递 | ||
| # 排队串行而非并发竞态;幂等由 from_state 匹配承担(重复事件=当前态已变=no-op) | ||
| # 排队串行而非并发竞态;幂等由 from_state 匹配承担(重复事件=当前态已变=no-op)。 | ||
| # 同卡两次 /claim 并发的双层防线(ADR-0055):本串行化使第二个 run 排队、届时 | ||
| # from_state 已不匹配=no-op(第一层);事件乱序时 arbiter CAS(422=lost-race) | ||
| # 兜底恰一胜者(第二层,ADR-0054) | ||
| concurrency: | ||
| group: conductor-issue-${{ github.event.issue.number }} | ||
| cancel-in-progress: false | ||
|
|
||
| permissions: | ||
| contents: read # checkout 本仓(transitions.yaml + gh-app-token.sh) | ||
| contents: read # checkout 本仓(transitions.yaml + gh-app-token.sh)+ arbiter(adjudicate.sh,ADR-0055) | ||
|
|
||
| jobs: | ||
| route: | ||
|
|
@@ -30,34 +37,51 @@ jobs: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| - name: 铸 App 令牌(AG-2:本仓单仓作用域) | ||
| # arbiter 受信 checkout(ADR-0055):conductor 只在 main 上下文运行事件路由, | ||
| # arbiter main 与本仓 transitions.yaml 同级信任——裁决内核不落本仓副本 | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| repository: Cloudbird-Software/arbiter | ||
| path: arbiter | ||
| persist-credentials: false | ||
| - name: 铸 App 令牌(AG-2:本仓 + arbiter 各一枚单仓作用域) | ||
| env: | ||
| CB_APP_ID: ${{ secrets.CB_APP_ID }} | ||
| AGENT_APP_SECRET: ${{ secrets.AGENT_APP_SECRET }} | ||
| run: | | ||
| TOKEN=$(REPO=.github CB_APP_ID="$CB_APP_ID" AGENT_APP_SECRET="$AGENT_APP_SECRET" \ | ||
| bash scripts/gh-app-token.sh) | ||
| echo "APP_TOKEN=$TOKEN" >>"$GITHUB_ENV" | ||
| # 第二枚(ADR-0055):REPO=arbiter 单仓作用域(租约宿主仓,installation | ||
| # #154584760)——adjudicate.sh 优先取 env 令牌、免二次铸币 | ||
| ATOKEN=$(REPO=arbiter CB_APP_ID="$CB_APP_ID" AGENT_APP_SECRET="$AGENT_APP_SECRET" \ | ||
| bash scripts/gh-app-token.sh) | ||
| echo "ARBITER_TOKEN=$ATOKEN" >>"$GITHUB_ENV" | ||
| # 事件路由与守卫:transitions.yaml 是唯一转移定义;guard 受限求值 | ||
| # (变量白名单注入、无内建);非授权=静默丢弃(回退标签、不评论、审计进 | ||
| # run 日志——AC-11)。注释/标签正文绝不进入任何求值(命令白名单精确匹配)。 | ||
| # W1-C3:/claim(T3)/release 前置转介 arbiter(ADR-0055;参数以 arbiter 仓 | ||
| # cli.py 为准);delivery-id=comment node_id(稳定幂等键,重投→arbiter noop)。 | ||
| - name: route(INV-02/09) | ||
| id: route | ||
| env: | ||
| APP_TOKEN: ${{ env.APP_TOKEN }} | ||
| ARBITER_TOKEN: ${{ env.ARBITER_TOKEN }} | ||
| GOV_TOKEN: ${{ secrets.GOVERNANCE_TOKEN }} | ||
| EVENT_NAME: ${{ github.event_name }} | ||
| ACTION: ${{ github.event.action }} | ||
| LABEL_NAME: ${{ github.event.label.name }} | ||
| COMMENT_BODY: ${{ github.event.comment.body }} | ||
| COMMENT_ASSOC: ${{ github.event.comment.author_association }} | ||
| COMMENT_NODE_ID: ${{ github.event.comment.node_id }} | ||
| ACTOR: ${{ github.actor }} | ||
| ISSUE_NUMBER: ${{ github.event.issue.number }} | ||
| ISSUE_TITLE: ${{ github.event.issue.title }} | ||
| REPO: ${{ github.repository }} | ||
| RUN_ID: ${{ github.run_id }} | ||
| run: | | ||
| python3 - <<'PYEOF' | ||
| import json, os, re, urllib.parse, urllib.request, urllib.error, yaml | ||
| import json, os, re, subprocess, urllib.parse, urllib.request, urllib.error, yaml | ||
|
|
||
| E = os.environ | ||
| ORG, REPO = "Cloudbird-Software", E["REPO"] | ||
|
|
@@ -88,7 +112,7 @@ jobs: | |
| elif E["EVENT_NAME"] == "issue_comment" and E["ACTION"] == "created": | ||
| head = (E.get("COMMENT_BODY") or "").strip().split() | ||
| token = head[0] if head else "" | ||
| if token in ("/start", "/claim", "/retry"): | ||
| if token in ("/start", "/claim", "/retry", "/release"): | ||
| ev = f"comment:{token}" | ||
| else: | ||
| raise SystemExit(0) # 普通评论:无审计面(噪音) | ||
|
|
@@ -117,13 +141,40 @@ jobs: | |
| audit(f"verdict=abort 多状态标签并存: {states}"); raise SystemExit(1) | ||
|
|
||
| # ---- 转移表匹配(幂等:from_state 不符=no-op)---- | ||
| # /release 不在表内(transitions.yaml 未列该事件)——纯租约面命令: | ||
| # 直达 arbiter 裁决,不产生任何标签转移(ADR-0055 决策 6) | ||
| table = yaml.safe_load(open("governance/transitions.yaml", encoding="utf-8")) | ||
| cands = [t for t in table["transitions"] if t["event"] == ev] | ||
| t = next((x for x in cands if x["from_state"] == current), None) | ||
| if t is None: | ||
| if t is None and ev != "comment:/release": | ||
| audit(f"event={ev} from={current} verdict=noop(无匹配转移——跳态/重复/未列组合)") | ||
| raise SystemExit(0) | ||
|
|
||
| # ---- arbiter 前置裁决(ADR-0055:/claim /release 转介;退出码三态)---- | ||
| # cwd 必须是 arbiter checkout 根(python -m arbiter.cli 的包根在那里) | ||
| ARBITER_DIR = os.path.join(os.getcwd(), "arbiter") | ||
| def adjudicate(command): | ||
| argv = ["bash", os.path.join(ARBITER_DIR, "scripts", "adjudicate.sh"), command, | ||
| "--card", f"{REPO}#{ISSUE}", "--sender", actor, | ||
| "--sender-role", role, | ||
| "--delivery-id", E.get("COMMENT_NODE_ID") or f"run-{E.get('RUN_ID', 'unknown')}", | ||
| "--event", "created", "--current-state", current, "--backend", "github"] | ||
| return subprocess.call(argv, cwd=ARBITER_DIR) | ||
|
|
||
| if ev == "comment:/release": | ||
| rc = adjudicate("/release") | ||
| if rc == 0: | ||
| audit(f"event={ev} from={current} sender_role={role} arbiter=allow " | ||
| f"verdict=ALLOWED release(租约已释放——无标签转移定义,纯租约面)") | ||
| raise SystemExit(0) | ||
| if rc == 1: | ||
| audit(f"event={ev} sender_role={role} verdict=DENIED-by-arbiter " | ||
| f"(非 holder/无租约/过期——无租约变更、无标签变更)") | ||
| raise SystemExit(0) | ||
| audit(f"event={ev} arbiter=infra rc={rc} verdict=ABORT " | ||
| f"(fail-closed——仲裁器失明不放行;delivery 幂等可安全重投)") | ||
| raise SystemExit(1) | ||
|
Comment on lines
+164
to
+176
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 在失败前写入
在所有可能失败的操作前写入 🤖 Prompt for AI Agents |
||
|
|
||
| # ---- guard 受限求值 ---- | ||
| env_vars = {"sender_role": role, "author_association": assoc, "label_set": labels} | ||
| ok = False | ||
|
|
@@ -143,10 +194,24 @@ jobs: | |
| if ev.startswith("label:"): | ||
| api(E["APP_TOKEN"], f"/repos/{REPO}/issues/{ISSUE}/labels/" | ||
| + urllib.parse.quote(ev[len("label:"):], safe=""), "DELETE") | ||
| audit(f"event={ev} transition={t['id']} sender_role={role} assoc={assoc} " | ||
| audit(f"event={ev} transition={t['id']} sender_role={role} assoc={assoc} " | ||
| f"verdict=DENIED-silent-drop(标签已回退,无评论,无阶段启动)") | ||
| raise SystemExit(0) | ||
|
|
||
| # ---- /claim 前置裁决(guard 先行——为注定拒绝的请求不建租约;ADR-0055)---- | ||
| if ev == "comment:/claim": | ||
| rc = adjudicate("/claim") | ||
| if rc == 1: | ||
| audit(f"event={ev} transition={t['id']} sender_role={role} assoc={assoc} " | ||
| f"verdict=DENIED-by-arbiter(无标签变更、无 assignee——对齐 silent-drop)") | ||
| raise SystemExit(0) | ||
| if rc != 0: | ||
| audit(f"event={ev} transition={t['id']} arbiter=infra rc={rc} verdict=ABORT " | ||
| f"(fail-closed——不许绕过仲裁;delivery 幂等可安全重投)") | ||
| raise SystemExit(1) | ||
| audit(f"event={ev} transition={t['id']} sender_role={role} arbiter=allow " | ||
| f"(租约已建——T3 落地;TTL 到期由下一 /claim 原子接管,ADR-0054)") | ||
|
|
||
|
Comment on lines
+201
to
+214
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift 使租约创建与 GitHub 状态写入保持一致。
检查所有写入结果。若后续写入失败,必须失败退出并补偿刚创建的租约,或使用可保证原子性的仲裁接口。 🤖 Prompt for AI Agents |
||
| # ---- 执行转移(状态标签写=App 身份,INV-02)---- | ||
| out = open(E["GITHUB_OUTPUT"], "a", encoding="utf-8") | ||
| action = t["action"] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1,40 @@ | ||
| # AGENTS.md | ||
|
|
||
| AI agent 进入本仓的工作契约(索引型,CG-1;细节按需读引用文件,不常驻上下文)。 | ||
| AI agent 进入本仓的工作契约(索引型,CG-1;治理仓豁免 ≤40 行——协议块+硬规则+索引三合一,ADR-0055 决策 4)。细节按需读引用文件,不常驻上下文。 | ||
|
|
||
| <!-- entry-protocol v1 --> | ||
|
|
||
| ### 入口协议(陌生 agent 从这里开始——宪法 §11 / ADR-0055) | ||
|
|
||
| 1. 取 ghcb(钉 SHA,禁浮动 main):`curl -sS -o ghcb https://raw.githubusercontent.com/Cloudbird-Software/.github/f72d9520706c8fca974d92456f65cae5c1412bb7/scripts/ghcb && chmod +x ghcb`(凭据用你自己的:`gh auth login` 或 `export GH_TOKEN=<PAT>`) | ||
| 2. 找活:`bash ghcb next [owner/repo]` → 列 state:ready 卡(卡 issue 是唯一工作凭证,无卡不开工) | ||
| 3. 认领:`bash ghcb claim <n> [owner/repo]` → 评论 /claim——conductor 转介 arbiter 原子 CAS 租约,先到先得;败者换下一张(`bash ghcb status <n>` 看持有者) | ||
| 4. 开工:`make card-test CARD=<n>`(读卡 AC、测试先行)→ `make gates-pr`(本地复现 CI 关卡) | ||
| 5. 提 PR:body 必带一行卡元数据 `Card: <owner>/<repo>#<n>`(`bash ghcb card-meta <n>` 生成;缺失=后续关卡 exit 3) | ||
| 6. front-desk 命令(卡 issue 评论,conductor 转介 arbiter 处理):/claim 认领 · /release 释放租约 · /retry 隔离回流 | ||
|
|
||
| <!-- /entry-protocol --> | ||
|
|
||
|
Comment on lines
+3
to
17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# 校验本仓 AGENTS.md 协议块与 template-service main 的一致性(与 drift §17 同判据)
set -uo pipefail
proto_block() {
awk '/<!-- entry-protocol v[0-9]+ -->/{f=1} f{print} /<!-- \/entry-protocol -->/{f=0}'
}
LOCAL=$(proto_block < AGENTS.md)
echo "== 本仓协议块($(printf '%s' "$LOCAL" | wc -c) 字节)=="
printf '%s\n' "$LOCAL"
REMOTE=$(curl -fsSL "https://raw.githubusercontent.com/Cloudbird-Software/template-service/main/AGENTS.md" || echo "__FETCH_FAIL__")
if [[ "$REMOTE" == "__FETCH_FAIL__" ]]; then
echo "!! template-service AGENTS.md 拉取失败(可能仓库私有或文件缺失)"
else
CANON=$(printf '%s\n' "$REMOTE" | proto_block)
echo "== canon 协议块($(printf '%s' "$CANON" | wc -c) 字节)=="
printf '%s\n' "$CANON"
if [[ "$LOCAL" == "$CANON" ]]; then echo "OK 逐字节一致"; else echo "DRIFT 不一致,diff:"; diff <(printf '%s\n' "$CANON") <(printf '%s\n' "$LOCAL"); fi
fiRepository: Cloudbird-Software/.github Length of output: 1100 🏁 Script executed: #!/bin/bash
set -u
echo '== AGENTS.md =='
cat -n AGENTS.md | sed -n '1,55p'
echo '== Relevant files =='
git ls-files | rg '(^|/)(ghcb|gh-app-token\.sh|drift-check\.sh|REPOS\.yaml|Makefile|AGENTS\.md|board-sync\.yml)$' || true
echo '== ghcb and token references =='
rg -n -C 3 'scripts/ghcb|gh-app-token|GH_TOKEN|entry_protocol|entry-protocol|board-sync|gates-pr|card-meta' . \
-g '!AGENTS.md' -g '!*.lock' || true
echo '== template-service AGENTS.md fetch status and protocol markers =='
tmp=$(mktemp)
status=$(curl -sS -L -o "$tmp" -w '%{http_code}' \
'https://raw.githubusercontent.com/Cloudbird-Software/template-service/main/AGENTS.md' || true)
echo "HTTP status: $status"
echo "bytes: $(wc -c < "$tmp")"
rg -n -C 2 'entry-protocol|入口协议|ghcb|gh-app-token' "$tmp" || true
rm -f "$tmp"
echo '== pinned ghcb fetch status =='
tmp=$(mktemp)
status=$(curl -sS -L -o "$tmp" -w '%{http_code}' \
'https://raw.githubusercontent.com/Cloudbird-Software/.github/f72d9520706c8fca974d92456f65cae5c1412bb7/scripts/ghcb' || true)
echo "HTTP status: $status"
echo "bytes: $(wc -c < "$tmp")"
head -n 8 "$tmp"
rm -f "$tmp"Repository: Cloudbird-Software/.github Length of output: 37486 🏁 Script executed: #!/bin/bash
set -u
echo '== drift-check §17 implementation =='
sed -n '687,735p' governance/drift-check.sh
echo '== entry_protocol declarations =='
sed -n '20,55p' governance/REPOS.yaml
echo '== local and template-service protocol-block extraction =='
proto_block() {
awk '/<!-- entry-protocol v[0-9]+ -->/{f=1} f{print} /<!-- \/entry-protocol -->/{f=0}'
}
local_block=$(proto_block < AGENTS.md)
remote_file=$(mktemp)
remote_status=$(curl -sS -L -o "$remote_file" -w '%{http_code}' \
'https://raw.githubusercontent.com/Cloudbird-Software/template-service/main/AGENTS.md' || true)
remote_block=$(proto_block < "$remote_file")
printf 'template-service HTTP=%s local_bytes=%s remote_bytes=%s remote_block_bytes=%s\n' \
"$remote_status" "$(printf %s "$local_block" | wc -c)" \
"$(wc -c < "$remote_file")" "$(printf %s "$remote_block" | wc -c)"
if [[ -z "$remote_block" ]]; then
echo 'template-service: MISSING protocol block'
fi
rm -f "$remote_file"
echo '== ghcb dispatch semantics (read-only source check) =='
sed -n '1,18p;65,90p' scripts/ghcb
echo '== gh-app-token invocation contract =='
sed -n '25,35p;90,116p' scripts/gh-app-token.sh
echo '== curl HTTP-error exit behavior =='
tmp=$(mktemp)
set +e
curl -sS -L -o "$tmp" -w 'status=%{http_code}\n' \
'https://raw.githubusercontent.com/Cloudbird-Software/.github/0000000000000000000000000000000000000000/scripts/ghcb'
curl_exit=$?
set -e
printf 'curl_exit_without_f=%s response_bytes=%s\n' "$curl_exit" "$(wc -c < "$tmp")"
rm -f "$tmp"Repository: Cloudbird-Software/.github Length of output: 8237
第 1 步的 🧰 Tools🪛 markdownlint-cli2 (0.23.2)[warning] 7-7: Heading levels should only increment by one level at a time (MD001, heading-increment) 🤖 Prompt for AI AgentsSource: Path instructions |
||
| ## 硬规则 | ||
|
|
||
| - 治理文件(governance/ standards/ scripts/ .github/ CODEOWNERS profile/)= C1 路径:PR 必须引用 ADR-NNNN,owner-only review(GOVERNANCE flows.governance_change;与 gate adr-required 机器检查同路径集) | ||
| - agent 写仓库身份 = GitHub App `cloudbrid-agent`(AG-1);令牌经 scripts/gh-app-token.sh,单仓作用域、1h 过期 | ||
| - 治理文件(governance/ standards/ scripts/ .github/ CODEOWNERS profile/ Makefile docs/)= C1 路径:PR 必须引用 ADR-NNNN,owner-only review(GOVERNANCE flows.governance_change;与 gate adr-required 机器检查同路径集) | ||
| - agent 写仓库身份 = GitHub App `cloudbrid-agent`(AG-1);令牌经 scripts/gh-app-token.sh,单仓作用域、1h 过期(本仓驻留 agent 直接用 `scripts/ghcb`,等价协议块下载版) | ||
| - 本仓只读治理声明;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 退出) | ||
| - 取 App 令牌:`GH_TOKEN=$(scripts/ghcb <repo>)`(缓存命中零网络;`--refresh` 强刷;Windows Git Bash 开箱可用——ADR-0044) | ||
| - 找活/认领(ADR-0051):`scripts/ghcb next`(列 state:ready 卡)→ `scripts/ghcb claim <n>`(评论 /claim,conductor 置 state:in-progress)→ `make gates-pr`(本地复现关卡,W1-C5 落地) | ||
|
|
||
| ## 索引 | ||
|
|
||
| | 主题 | 文件 | | ||
| |---|---| | ||
| | 治理总声明(域/措施/流程) | governance/GOVERNANCE.yaml | | ||
| | 组织仓库地图 | governance/REPOS.yaml | | ||
| | 期望状态(漂移真源) | 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 反馈通道 / App 权限与工作流变更通道,ADR-0031/0032/0045) | standards/automation/ | | ||
| | 原型 profiles / 注册条目 | Cloudbird-Software/agent-registry | | ||
| ## 常用命令(本仓驻留) | ||
|
|
||
| - 校验本仓声明:`.github/workflows/gate.yml`(本地等价:`make gates-pr`——bash -n + yaml 全量解析) | ||
| - 漂移检测:`GH_TOKEN=<org admin> bash governance/drift-check.sh`(每日 CI 自动跑;§17=入口协议块对账) | ||
| - 修复循环上限执法:`GH_TOKEN=<org admin> bash governance/auto-fix-limit.sh`(小时级;`AUTOFIX_DRY_RUN=1` 只报告) | ||
| - 成本熔断检查:`GH_TOKEN=<org admin> bash governance/cost-check.sh`(6h;`COST_USAGE_MINUTES_OVERRIDE=<n>` 注入测试) | ||
| - 漂移修复:`GH_TOKEN=<org admin> bash governance/apply.sh`(幂等;失败 loud 退出)· 新仓初始化:`bash scripts/new-repo-init.sh <name>` | ||
| - 取 App 令牌:`GH_TOKEN=$(scripts/ghcb <repo>)`(缓存命中零网络;`--refresh` 强刷,ADR-0044) | ||
| - factory-floor 板/账本手动刷新:Actions → board-sync(dispatch-only;日常 cron 归 butler-ledger,ADR-0055) | ||
|
|
||
| ## 索引(用到再读) | ||
|
|
||
| - 治理总声明 governance/GOVERNANCE.yaml · 组织地图 governance/REPOS.yaml · 期望状态 governance/expected-state.json | ||
| - 政策集 governance/policy/(languages.yaml、testing.yaml、无人值守阈值 automation-limits.yaml ADR-0040;入口协议/卡元数据=ADR-0055) | ||
| - agent 标准 schema standards/agent/ · 自动化规范 standards/automation/(ADR-0031/0032/0045)· 注册条目与 ADR → agent-registry 仓 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Workflow uses governance_token directly
📘 Rule violation⛨ SecurityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools