-
Notifications
You must be signed in to change notification settings - Fork 0
feat: 组织地图 REPOS.yaml 与仓申报漂移检测 #7
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
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,65 @@ | ||
| version: 1 | ||
| org: Cloudbird-Software | ||
| # ============================================================================ | ||
| # 组织地图(repo registry)—— 一文件看清治理版图 | ||
| # 目的: 结构层导航(人/AI 不必逐仓打开即知全貌)+ 漂移检测锚点。 | ||
| # 替代 submodule 方案:无指针过期、无 recursive clone 问题。 | ||
| # 规则(GM-4): | ||
| # - 线上存在的仓必须在下方申报;未申报 = drift(drift-check §7b) | ||
| # - status: active 的仓必须存在且 visibility 一致(drift-check §7a) | ||
| # - status: planned = 尚未建仓(不参与检测);exempt = 申报但不治理 | ||
| # - 新仓初始化后必须申报入图(flows.new_repo step 4) | ||
| # ============================================================================ | ||
| layers: | ||
| L0: 标准与治理(intent:GOVERNANCE / 标准 schema / 工作流实现) | ||
| L1: 注册条目(声明:agent / skill / tool / team / 模型别名 / ADR) | ||
| L2: 实现(代码:框架、工具、业务项目) | ||
| L3: 数据(不进 git:事件流 / 轨迹 / 团队运行态) | ||
|
|
||
| repos: | ||
| - name: .github | ||
| layer: L0 | ||
| visibility: public | ||
| status: active | ||
| role: 治理总仓——GOVERNANCE/rulesets/expected-state/policies/agent 标准 schema/初始化与漂移脚本 | ||
| key_paths: [governance/, standards/agent/, scripts/] | ||
|
|
||
| - name: CI-Workflows | ||
| layer: L0 | ||
| visibility: public | ||
| status: active | ||
| role: 可复用工作流仓——全部项目仓 gate 的唯一实现,业务仓引用 @v1 | ||
| key_paths: [.github/workflows/] | ||
|
|
||
| - name: agent-registry | ||
| layer: L1 | ||
| visibility: private | ||
| status: active | ||
| role: 注册层——agent/skill/tool/team 声明 + 模型注册表(models.yaml) + ADR;AR-2 状态门禁校验器 | ||
| key_paths: [registry/, decisions/, scripts/validate.py] | ||
| policies: [agent_runtime] | ||
|
|
||
| - name: template-service | ||
| layer: L2 | ||
| visibility: public | ||
| status: active | ||
| role: 项目模板仓——新仓由此派生,自动继承 gate/护栏/AGENTS.md 骨架 | ||
| key_paths: [AGENTS.md, .github/workflows/ci.yml, docs/ARCHITECTURE.md] | ||
|
|
||
| - name: openjiuwen | ||
| layer: L2 | ||
| visibility: private | ||
| status: planned | ||
| role: 编排框架私有仓(推入/维护)——多智能体运行时 + LLM Gateway 部署配置(deploy/llm-gateway) | ||
|
|
||
| - name: agent-tools | ||
| layer: L2 | ||
| visibility: private | ||
| status: planned | ||
| role: 自研工具实现仓——被 tool 声明的 implementation 字段引用 | ||
|
|
||
| - name: AI_Web_School | ||
| layer: L2 | ||
| visibility: public | ||
| status: exempt | ||
| role: 历史产品仓——申报在册但豁免治理基线(repo_baseline.exclude_repos) | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -113,6 +113,29 @@ else | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| drift "github app '$(jq -r .github_app.name "$EXPECTED")' 不存在或 id 不符" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ---------- 7. 组织地图(REPOS.yaml):存在性 / visibility / 未申报仓 ---------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if python3 -c 'import yaml' 2>/dev/null; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| REPO_MAP=$(python3 -c 'import yaml,json,sys;print(json.dumps(yaml.safe_load(open(sys.argv[1]))))' "$DIR/REPOS.yaml") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 7a. active 仓:必须存在且 visibility 一致 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=$'\t' read -r r want_vis; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [[ -n "$r" ]] || continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RR=$(api "https://api.github.com/repos/$ORG/$r") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$(jq -r 'if .message then .message else "" end' <<<"$RR")" == "Not Found" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| drift "REPOS.yaml 申报的 active 仓 '$r' 不存在"; continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| got_vis=$(jq -r 'if .private then "private" else "public" end' <<<"$RR") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [[ "$got_vis" == "$want_vis" ]] || drift "repo '$r' visibility=$got_vis 期望=$want_vis" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ok "REPOS map '$r'" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done < <(jq -r '.repos[] | select(.status=="active") | "\(.name)\t\(.visibility)"' <<<"$REPO_MAP") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 7b. 线上仓必须在图中申报(任何 status 均可,未申报即漂移) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for r in $REPOS; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jq -e --arg r "$r" '[.repos[].name] | index($r) != null' <<<"$REPO_MAP" >/dev/null \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| || drift "线上仓 '$r' 未在 governance/REPOS.yaml 申报(补申报,或标 exempt 注明原因)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+131
to
+134
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. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
ORG="${ORG:-Cloudbird-Software}"
first_page_count="$(gh api "/orgs/$ORG/repos?per_page=100" --jq 'length')"
all_pages_count="$(gh api --paginate "/orgs/$ORG/repos?per_page=100" --jq '.[].name' | wc -l | tr -d ' ')"
printf 'first_page=%s\nall_pages=%s\n' "$first_page_count" "$all_pages_count"Repository: Cloudbird-Software/.github Length of output: 189 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- governance/drift-check.sh ---'
sed -n '70,145p' governance/drift-check.sh
printf '%s\n' '--- references to drift-check and PyYAML ---'
rg -n -C 3 'drift-check|PyYAML|yaml|python|REPOS=' .github governance 2>/dev/null || trueRepository: Cloudbird-Software/.github Length of output: 17434 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- drift-check.sh header and API helper ---'
sed -n '1,35p' governance/drift-check.sh
printf '%s\n' '--- workflow runtime setup ---'
cat -n .github/workflows/governance-drift.yml | sed -n '1,32p'
printf '%s\n' '--- repository map entry count ---'
python3 - <<'PY'
from pathlib import Path
import re
text = Path("governance/REPOS.yaml").read_text()
print("repo_entries=" + str(len(re.findall(r"^ - name:", text, re.M))))
PYRepository: Cloudbird-Software/.github Length of output: 2748 遍历 GitHub API 的全部分页结果
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "SKIP REPOS.yaml 校验(环境缺 python3+pyyaml;GitHub runner 自带)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+117
to
+137
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 | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 3 'drift-check\.sh|PyYAML|pyyaml|pip.*yaml' .github/workflows governanceRepository: Cloudbird-Software/.github Length of output: 2840 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- governance/drift-check.sh ---'
sed -n '1,180p' governance/drift-check.sh
printf '%s\n' '--- .github/workflows/governance-drift.yml ---'
sed -n '1,90p' .github/workflows/governance-drift.yml
printf '%s\n' '--- repository metadata ---'
rg -n 'REPOS\.yaml|pyyaml|PyYAML|setup-python|pip install|ubuntu-' .github governance README.md 2>/dev/null || trueRepository: Cloudbird-Software/.github Length of output: 9825 🏁 Script executed: #!/bin/bash
set -u
python3 - <<'PY'
from pathlib import Path
p = Path("governance/drift-check.sh")
text = p.read_text()
for needle in ("set -uo pipefail", "drift()", "DRIFTS", "exit ", "SKIP REPOS.yaml"):
print(f"--- {needle} ---")
for i, line in enumerate(text.splitlines(), 1):
if needle in line:
print(f"{i}: {line}")
PY
printf '%s\n' '--- workflow dependency commands ---'
sed -n '1,55p' .github/workflows/governance-drift.yml
printf '%s\n' '--- all dependency references ---'
rg -n -i 'pyyaml|pyyaml|pip(3)?[[:space:]]+install|python(3)?[[:space:]]+-m[[:space:]]+pip|setup-python' .github governance . 2>/dev/null | head -200Repository: Cloudbird-Software/.github Length of output: 2591 🌐 Web query:
💡 Result: On GitHub-hosted Ubuntu runners (including the ubuntu-latest image), PyYAML is not explicitly maintained as a preinstalled software package by GitHub [1]. While some users have observed PyYAML being present in certain environments, this is typically due to it being a dependency of other preinstalled tools (such as those managed by Miniconda or system Python packages) rather than an explicit inclusion policy [2][1]. GitHub does not document implicitly installed packages in its official runner software lists [2]. Because preinstalled software lists change frequently as images are updated, GitHub recommends that users install required dependencies—such as PyYAML—explicitly during the workflow execution to ensure stability and predictability [3][1]. If your workflow requires PyYAML, the recommended practice is to install it using pip as part of your CI/CD job: - run: pip install PyYAML You can verify the specific software included in your runner's image by checking the "Included Software" link found within the "Runner Image" section of your workflow job's "Set up job" log [3]. Citations:
🏁 Script executed: #!/bin/bash
set +e
out=$(
bash -c '
set -uo pipefail
DRIFTS=0
drift(){ echo "DRIFT $1"; DRIFTS=$((DRIFTS+1)); }
if python3 -c "import definitely_missing_yaml_module" 2>/dev/null; then
:
else
echo "SKIP"
fi
if [[ $DRIFTS -gt 0 ]]; then exit 1; fi
echo "SUCCESS"
' 2>&1
)
status=$?
printf 'missing-dependency branch status=%s\n%s\n' "$status" "$out"Repository: Cloudbird-Software/.github Length of output: 212 【严重级别:高】缺少 Python/PyYAML 时必须使 GM-4 校验失败。 当前分支仅输出 建议修改 else
- echo "SKIP REPOS.yaml 校验(环境缺 python3+pyyaml;GitHub runner 自带)"
+ drift "无法校验 REPOS.yaml:缺少 python3 或 PyYAML"
fi📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "----------------------------------------" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $DRIFTS -gt 0 ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "结果: $DRIFTS 项漂移。修复: bash governance/apply.sh 或手动改回" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,8 +12,12 @@ | |
|
|
||
| ## 仓库 | ||
|
|
||
| | 仓库 | 用途 | | ||
| |---|---| | ||
| | [CI-Workflows](https://github.com/Cloudbird-Software/CI-Workflows) | 可复用工作流(唯一真相源) | | ||
| | [template-service](https://github.com/Cloudbird-Software/template-service) | 新项目模板 | | ||
| | [AI_Web_School](https://github.com/Cloudbird-Software/AI_Web_School) | 产品仓库 | | ||
| 组织地图(结构层导航的唯一真源):[governance/REPOS.yaml](../governance/REPOS.yaml) | ||
|
|
||
| | 仓库 | 层 | 用途 | | ||
| |---|---|---| | ||
| | [.github](https://github.com/Cloudbird-Software/.github) | L0 | 治理总仓:GOVERNANCE / 标准 schema / 漂移检测 | | ||
| | [CI-Workflows](https://github.com/Cloudbird-Software/CI-Workflows) | L0 | 可复用工作流(唯一真相源) | | ||
| | [agent-registry](https://github.com/Cloudbird-Software/agent-registry) | L1 | agent/skill/tool/team 声明 + 模型注册表 + ADR(私有) | | ||
|
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 | 🟡 Minor | ⚡ Quick win 修正仓库可见性声明。 Line 3 声明“所有仓库公开”,但此行将 🤖 Prompt for AI AgentsSource: Path instructions |
||
| | [template-service](https://github.com/Cloudbird-Software/template-service) | L2 | 新项目模板 | | ||
| | [AI_Web_School](https://github.com/Cloudbird-Software/AI_Web_School) | L2 | 产品仓库 | | ||
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.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
更正流程步骤编号。
flows.new_repo的“申报入图”是第 3 个步骤,不是step 4。错误编号会导致维护者定位到错误步骤。将step 4改为step 3,或改为“flows.new_repo申报步骤”。🤖 Prompt for AI Agents