From 147e86d1de1472b26248097d1e1d080bd9f0f3bd Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 13 May 2026 09:30:50 +0800 Subject: [PATCH] docs(security): add ref truth classification [skip ci] --- docs/LOGBOOK.md | 31 +- ...ol_ref_truth_classification_v1.schema.json | 162 + ...WOOOP-MIRROR-ONLY-CONSUMPTION-CHECKLIST.md | 5 +- ...ECURITY-SUPPLYCHAIN-INTEGRATION-HANDOFF.md | 7 +- .../GITEA-GITHUB-MIGRATION-INVENTORY.md | 9 +- ...SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md | 5 +- .../SECURITY-SUPPLY-CHAIN-PROGRESS.md | 11 +- .../SOURCE-CONTROL-MIGRATION-MATRIX.md | 9 +- .../security/SOURCE-CONTROL-RECONCILE-PLAN.md | 5 +- ...SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md | 135 + ...pply-chain-contract-manifest.snapshot.json | 22 +- ...ource-control-reconcile-plan.snapshot.json | 2 +- ...rol-ref-truth-classification.snapshot.json | 4144 +++++++++++++++++ .../security/source-control-reconcile-plan.py | 3 + ...source-control-ref-truth-classification.py | 371 ++ 15 files changed, 4904 insertions(+), 17 deletions(-) create mode 100644 docs/schemas/source_control_ref_truth_classification_v1.schema.json create mode 100644 docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md create mode 100644 docs/security/source-control-ref-truth-classification.snapshot.json create mode 100644 scripts/security/source-control-ref-truth-classification.py diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 2b2b2be1..6079a548 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,32 @@ +## 2026-05-13 | Security Supply Chain refs 真相來源分類草案 + +**背景**:branch/tag 明細 diff 已能看出 refs 差異,但 AwoooP 與 repo owner 仍需要下一層「哪些要真相來源判定、哪些只是 deprecated 候選、哪些 tag 要保留」的審核隊列;本輪仍不做同步、不切主控。 + +**本次交付**: +- 新增 `scripts/security/source-control-ref-truth-classification.py`,只讀取 `source-control-ref-detail-diff.snapshot.json`,不呼叫遠端 Git、不 fetch、不 push、不刪 refs。 +- 新增 `docs/schemas/source_control_ref_truth_classification_v1.schema.json`。 +- 產出 `docs/security/source-control-ref-truth-classification.snapshot.json` 與 `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md`。 +- 更新 `SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST`,contract count 從 15 增至 16。 +- 同步更新 AwoooP mirror-only checklist、Security Supply Chain 整體進度、Gitea/GitHub migration inventory、Source Control 遷移矩陣與 AwoooP handoff。 + +**分類結果**: +- 總計 3 個 refs-blocked repos、141 個 refs review items。 +- 4 個 `manual_truth_required`:主要是 `main` SHA 不一致與 `awoooi/dev`。 +- 114 個 `manual_review_deprecated_candidate`:`drift/adopt-*` 類分支先列為可能封存/降級候選,但不得自動刪除。 +- 3 個 `manual_review_release_tag`:Gitea-only release tags 需確認 release / artifact / deploy marker。 +- 20 個 `manual_review_github_only`:`wooo-aiops` 的 GitHub-only branch / UAT tags 需人工判定。 + +**邊界**: +- AwoooP 可 mirror classification、顯示 review lane、建立單 repo / 單 ref owner decision queue。 +- 仍不得 fetch refs、push refs、force push、delete refs、建立 repo、改 visibility、切 GitHub primary、停用 Gitea 或搬 secret value。 + +**驗證**: +- `source-control-ref-truth-classification.py` 產生 3 repo / 141 items snapshot。 +- JSON / schema / manifest path 檢查通過。 +- `scripts/security/*.py` 可編譯。 +- `git diff --check` 通過。 +- diff 敏感資訊掃描未命中本輪 token / credential pattern。 + ## 2026-05-13 | Security Supply Chain branch/tag 明細 diff 與 PR #117 累積同步 **背景**:統帥批准繼續推進後,本輪先把最新 `gitea/main` 合入 Security Supply Chain PR #117,保留 AwoooP T3/T4/T5 已推版紀錄,再進行 refs-blocked repo 的 branch/tag 明細盤點。此階段仍只做 read-only evidence,不執行同步。 @@ -18,7 +47,7 @@ **累積狀態**: - PR `#117` 已包含 docs-only / contracts-first Security Supply Chain scaffold、approval board、draft reconcile plan 與 ref detail diff。 -- Contract manifest 現為 15 個主要 contract;AwoooP 可 mirror / read-only policy / approval candidate 消費,但不得作 execution router。 +- 當輪 contract manifest 為 15 個主要 contract;後續 refs 真相來源分類已再擴充至 16 個。 - GitHub primary、repo 建立、visibility 修改、refs sync、deploy 全部仍 blocked。 **驗證**: diff --git a/docs/schemas/source_control_ref_truth_classification_v1.schema.json b/docs/schemas/source_control_ref_truth_classification_v1.schema.json new file mode 100644 index 00000000..02e636fd --- /dev/null +++ b/docs/schemas/source_control_ref_truth_classification_v1.schema.json @@ -0,0 +1,162 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:awoooi:source-control-ref-truth-classification-v1", + "title": "AWOOOI Source Control Ref Truth Classification (v1)", + "description": "將 Gitea / GitHub branch/tag read-only diff 轉成真相來源候選與人工審核分類;不授權 refs sync。", + "type": "object", + "required": [ + "schema_version", + "status", + "date", + "default_mode", + "source_snapshot", + "summary", + "still_forbidden", + "repos" + ], + "properties": { + "schema_version": { + "const": "source_control_ref_truth_classification_v1" + }, + "status": { + "type": "string", + "enum": ["draft_blocked"] + }, + "date": { + "type": "string" + }, + "default_mode": { + "type": "string", + "enum": ["classification_only"] + }, + "source_snapshot": { + "type": "string" + }, + "summary": { + "type": "object", + "required": [ + "repo_count", + "total_items", + "manual_truth_required_count", + "deprecated_candidate_count", + "release_tag_review_count", + "github_only_review_count" + ], + "properties": { + "repo_count": {"type": "integer", "minimum": 0}, + "total_items": {"type": "integer", "minimum": 0}, + "manual_truth_required_count": {"type": "integer", "minimum": 0}, + "deprecated_candidate_count": {"type": "integer", "minimum": 0}, + "release_tag_review_count": {"type": "integer", "minimum": 0}, + "github_only_review_count": {"type": "integer", "minimum": 0} + }, + "additionalProperties": false + }, + "still_forbidden": { + "type": "array", + "items": {"type": "string"} + }, + "repos": { + "type": "array", + "items": { + "type": "object", + "required": [ + "gitea_repo", + "github_repo", + "risk", + "awooop_consumption", + "item_count", + "items" + ], + "properties": { + "gitea_repo": {"type": "string"}, + "github_repo": {"type": "string"}, + "risk": { + "type": "string", + "enum": ["LOW", "MEDIUM", "HIGH"] + }, + "awooop_consumption": { + "type": "string", + "enum": ["mirror_only", "approval_candidate"] + }, + "item_count": {"type": "integer", "minimum": 0}, + "items": { + "type": "array", + "items": {"$ref": "#/$defs/classificationItem"} + } + }, + "additionalProperties": false + } + } + }, + "$defs": { + "classificationItem": { + "type": "object", + "required": [ + "ref_type", + "ref_name", + "lane", + "risk", + "proposed_truth_source", + "classification", + "reason", + "next_review", + "gitea_sha", + "github_sha", + "allowed_now", + "forbidden_actions" + ], + "properties": { + "ref_type": { + "type": "string", + "enum": ["branch", "tag"] + }, + "ref_name": {"type": "string"}, + "lane": { + "type": "string", + "enum": [ + "main_truth_required", + "active_branch_truth_required", + "archive_or_deprecate_candidate", + "release_tag_missing_on_github", + "github_only_manual_review", + "github_only_uat_tag", + "manual_review" + ] + }, + "risk": { + "type": "string", + "enum": ["LOW", "MEDIUM", "HIGH"] + }, + "proposed_truth_source": { + "type": "string", + "enum": ["gitea", "github", "manual_required", "deprecated_candidate"] + }, + "classification": { + "type": "string", + "enum": [ + "manual_truth_required", + "manual_review_deprecated_candidate", + "manual_review_release_tag", + "manual_review_github_only", + "manual_review" + ] + }, + "reason": {"type": "string"}, + "next_review": {"type": "string"}, + "gitea_sha": {"type": "string"}, + "github_sha": {"type": "string"}, + "allowed_now": { + "type": "array", + "items": {"type": "string"} + }, + "forbidden_actions": { + "type": "array", + "items": {"type": "string"} + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false +} diff --git a/docs/security/AWOOOP-MIRROR-ONLY-CONSUMPTION-CHECKLIST.md b/docs/security/AWOOOP-MIRROR-ONLY-CONSUMPTION-CHECKLIST.md index fe67bd87..13741fc0 100644 --- a/docs/security/AWOOOP-MIRROR-ONLY-CONSUMPTION-CHECKLIST.md +++ b/docs/security/AWOOOP-MIRROR-ONLY-CONSUMPTION-CHECKLIST.md @@ -2,7 +2,7 @@ | 項目 | 內容 | |------|------| -| 日期 | 2026-05-12 | +| 日期 | 2026-05-13 | | 狀態 | 初版,供 AwoooP Session 只讀消費 | | 範圍 | Kali / Code Review / Codex / Gitea / GitHub 資安供應鏈事件 | | 低摩擦 policy | `docs/security/SECURITY-LOW-FRICTION-ROLLOUT-POLICY.md` | @@ -36,6 +36,7 @@ AwoooP 初期不得直接啟動掃描、不得呼叫 Codex patch runner、不得 | `source_control_approval_board_v1` | 逐 repo owner / visibility / canonical / refs 決策 board | Approval queue、PR reviewer handoff | approval-only | 只顯示決策隊列,不執行 board item | | `source_control_reconcile_plan_v1` | refs-blocked repo draft reconcile plan | Approval candidate、migration reviewer handoff | approval-only | 只顯示草案,不 push refs、不切 primary | | `source_control_ref_detail_diff_v1` | refs-blocked repo branch/tag 明細 diff | Migration reviewer evidence | mirror-only | 只顯示 diff,不 fetch、不 push、不刪 refs | +| `source_control_ref_truth_classification_v1` | refs diff 真相來源與 deprecated 候選分類 | Repo owner review queue、migration reviewer handoff | approval-only | 只顯示分類與人工判定隊列,不執行 sync/delete | | `local_repo_canonical_probe_v1` | 本機 working tree lineage 比對 | Canonical decision evidence | mirror-only | 不自動合併、不自動建 repo、不刪除 | | `git_remote_refs_probe_v1` | 指定 repo remote refs read-only probe | Source readiness evidence | mirror-only | 不 fetch、不 push、不自動 mirror | | `approval_required_event_v1` | 上述事件的高風險 gate | Approval queue、Audit | approval-only | `blocked_until_approved=true` | @@ -87,6 +88,7 @@ AwoooP 初期不得直接啟動掃描、不得呼叫 Codex patch runner、不得 | `source_control_approval_board_v1.pending_approval_count>0` | `approve_required` | 顯示逐 repo 決策隊列,不執行 repo 建立、visibility 修改、refs sync | | `source_control_reconcile_plan_v1.status=draft_blocked` | `approve_required` | 只顯示 refs reconcile 草案與 gate,不執行 sync | | `source_control_ref_detail_diff_v1.status=draft_blocked` | `observe` | 顯示 branch/tag 明細 diff,支援人工 review | +| `source_control_ref_truth_classification_v1.status=draft_blocked` | `approve_required` | 顯示 main/dev 真相來源、drift deprecated 候選、release / UAT tag review lane,不執行分類結果 | | `local_repo_canonical_probe_v1.status=unrelated` | `approve_required` | 禁止自動合併,需人工 canonical 判定 | | `git_remote_refs_probe_v1.status=ok` | `observe` | 可作 source evidence,但仍需 GitHub target 與 approval | | `security_rollout_policy_v1.enforcement_level=mirror_only` | `observe` | 只顯示 policy,不阻擋既有流程 | @@ -130,6 +132,7 @@ AwoooP 初期不得直接啟動掃描、不得呼叫 Codex patch runner、不得 | Source Control approval board | `docs/security/source-control-approval-board.snapshot.json` / `docs/security/SOURCE-CONTROL-APPROVAL-BOARD.md` | | Source Control draft reconcile plan | `docs/security/source-control-reconcile-plan.snapshot.json` / `docs/security/SOURCE-CONTROL-RECONCILE-PLAN.md` | | Source Control branch/tag detail diff | `docs/security/source-control-ref-detail-diff.snapshot.json` / `docs/security/SOURCE-CONTROL-REF-DETAIL-DIFF.md` | +| Source Control ref truth classification | `docs/security/source-control-ref-truth-classification.snapshot.json` / `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md` | | 本機 repo canonical lineage snapshot | `docs/security/local-repo-canonical-ewoooc-momo.snapshot.json` / `docs/security/LOCAL-REPO-CANONICAL-EWOOOC-MOMO-SNAPSHOT.md` | | Internal 110 refs snapshot | `docs/security/git-remote-refs-bitan-tsenyang.snapshot.json` / `docs/security/GIT-REMOTE-REFS-BITAN-TSENYANG-SNAPSHOT.md` | | wooo-infra-config refs snapshot | `docs/security/git-remote-refs-wooo-infra-config.snapshot.json` / `docs/security/GIT-REMOTE-REFS-WOOO-INFRA-CONFIG-SNAPSHOT.md` | diff --git a/docs/security/AWOOOP-SECURITY-SUPPLYCHAIN-INTEGRATION-HANDOFF.md b/docs/security/AWOOOP-SECURITY-SUPPLYCHAIN-INTEGRATION-HANDOFF.md index d2173959..7f017e6e 100644 --- a/docs/security/AWOOOP-SECURITY-SUPPLYCHAIN-INTEGRATION-HANDOFF.md +++ b/docs/security/AWOOOP-SECURITY-SUPPLYCHAIN-INTEGRATION-HANDOFF.md @@ -145,7 +145,7 @@ Schema:`docs/schemas/security_supply_chain_contract_manifest_v1.schema.json` "schema_version": "security_supply_chain_contract_manifest_v1", "status": "draft", "default_enforcement_level": "mirror_only", - "contract_count": 12 + "contract_count": 16 } ``` @@ -541,6 +541,8 @@ Console 初期不提供高風險 action button。 2026-05-13 branch/tag detail diff 追加:已新增 `scripts/security/source-control-ref-detail-diff.py`、`docs/schemas/source_control_ref_detail_diff_v1.schema.json`,並產出 `docs/security/source-control-ref-detail-diff.snapshot.json` 與 `docs/security/SOURCE-CONTROL-REF-DETAIL-DIFF.md`。最新 read-only diff 忽略本 PR 分支後,`awoooi` 仍有 Gitea-only branches 115、Gitea-only tags 2、main SHA 不一致;`clawbot-v5` main SHA 不一致且 GitHub 缺 Gitea tag;`wooo-aiops` GitHub 有 1 條額外 branch 與 19 個 GitHub-only tags。AwoooP 可 mirror 此 evidence,但不得 fetch、push、delete refs 或切 primary。 +2026-05-13 ref truth classification 追加:已新增 `scripts/security/source-control-ref-truth-classification.py`、`docs/schemas/source_control_ref_truth_classification_v1.schema.json`,並產出 `docs/security/source-control-ref-truth-classification.snapshot.json` 與 `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md`。目前 141 個 refs review items 已拆成 4 個 `manual_truth_required`、114 個 `manual_review_deprecated_candidate`、3 個 `manual_review_release_tag`、20 個 `manual_review_github_only`。AwoooP 可建立 repo owner review queue,但不得把分類結果直接執行成 refs sync、delete、force push 或 GitHub primary switch。 + 2026-05-12 public search / canonical 追加:Gitea public search 在未提供 token 時可見 `wooo/awoooi`、`wooo/ewoooc`。已新增 `docs/security/SOURCE-CONTROL-CANONICAL-DECISION-TABLE.md`,其中 `wooo/ewoooc`、`root/momo-pro-system`、`momo-pro-system`、`momo_pro_system` 仍需人工判定 canonical 關係,不得自動合併。 2026-05-12 GitHub target probe 追加:已新增 `scripts/security/github-target-probe.py`、`docs/schemas/github_target_probe_v1.schema.json` 與 `docs/security/github-target-probe.snapshot.json`。8 個候選中 5 個可讀,`owenhytsai/ewoooc`、`owenhytsai/bitan-pharmacy`、`owenhytsai/tsenyang-website` 為 `not_found_or_private`。 @@ -603,6 +605,8 @@ Console 初期不提供高風險 action button。 - [security_rollout_policy_v1 snapshot](/Users/ogt/awoooi/docs/security/security-rollout-policy.snapshot.json) - [Security Supply Chain contract manifest](/Users/ogt/awoooi/docs/security/SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md) - [security_supply_chain_contract_manifest_v1 snapshot](/Users/ogt/awoooi/docs/security/security-supply-chain-contract-manifest.snapshot.json) +- [Source Control ref truth classification](/Users/ogt/awoooi/docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md) +- [source_control_ref_truth_classification_v1 snapshot](/Users/ogt/awoooi/docs/security/source-control-ref-truth-classification.snapshot.json) - [本機 repo canonical lineage snapshot](/Users/ogt/awoooi/docs/security/LOCAL-REPO-CANONICAL-EWOOOC-MOMO-SNAPSHOT.md) - [local_repo_canonical_probe_v1 snapshot](/Users/ogt/awoooi/docs/security/local-repo-canonical-ewoooc-momo.snapshot.json) - [本機 repo canonical lineage script](/Users/ogt/awoooi/scripts/security/local-repo-canonical-probe.py) @@ -628,6 +632,7 @@ Console 初期不提供高風險 action button。 - [github_target_repo_approval_package_v1 schema](/Users/ogt/awoooi/docs/schemas/github_target_repo_approval_package_v1.schema.json) - [security_rollout_policy_v1 schema](/Users/ogt/awoooi/docs/schemas/security_rollout_policy_v1.schema.json) - [security_supply_chain_contract_manifest_v1 schema](/Users/ogt/awoooi/docs/schemas/security_supply_chain_contract_manifest_v1.schema.json) +- [source_control_ref_truth_classification_v1 schema](/Users/ogt/awoooi/docs/schemas/source_control_ref_truth_classification_v1.schema.json) - [local_repo_canonical_probe_v1 schema](/Users/ogt/awoooi/docs/schemas/local_repo_canonical_probe_v1.schema.json) - [git_remote_refs_probe_v1 schema](/Users/ogt/awoooi/docs/schemas/git_remote_refs_probe_v1.schema.json) - [approval_required_event_v1 schema](/Users/ogt/awoooi/docs/schemas/approval_required_event_v1.schema.json) diff --git a/docs/security/GITEA-GITHUB-MIGRATION-INVENTORY.md b/docs/security/GITEA-GITHUB-MIGRATION-INVENTORY.md index c7dba33f..b617cb24 100644 --- a/docs/security/GITEA-GITHUB-MIGRATION-INVENTORY.md +++ b/docs/security/GITEA-GITHUB-MIGRATION-INVENTORY.md @@ -25,6 +25,7 @@ | GitHub target repo-by-repo approval package | `docs/security/GITHUB-TARGET-REPO-APPROVAL-PACKAGE.md` / `docs/security/github-target-repo-approval-package.snapshot.json` | | Source Control draft reconcile plan | `docs/security/SOURCE-CONTROL-RECONCILE-PLAN.md` / `docs/security/source-control-reconcile-plan.snapshot.json` | | Source Control branch/tag detail diff | `docs/security/SOURCE-CONTROL-REF-DETAIL-DIFF.md` / `docs/security/source-control-ref-detail-diff.snapshot.json` | +| Source Control ref truth classification | `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md` / `docs/security/source-control-ref-truth-classification.snapshot.json` | | Source Control 遷移矩陣 | `docs/security/SOURCE-CONTROL-MIGRATION-MATRIX.md` | | Canonical repo 判定表 | `docs/security/SOURCE-CONTROL-CANONICAL-DECISION-TABLE.md` | @@ -47,6 +48,7 @@ - `wooo-infra-config` 的 GitHub remote 與本機 `main` 對齊;110 internal remote 目前 read-only probe 不可讀,需判斷是否為舊 remote、mirror 或權限問題。 - GitHub target 決策表已建立,8 個候選中 7 個需人工批准;其中 `ewoooc`、`bitan-pharmacy`、`tsenyang-website` 在 target visibility / owner 決策前不得自動建立或同步。 - GitHub target repo-by-repo approval package 已建立,7 個 approval-required targets 拆成 refs reconcile、target 建立 / 授權、internal remote 用途確認三條路徑;此 package 採低摩擦原則,只 gate 高風險執行,不阻擋 read-only evidence。 +- Source Control ref truth classification 已建立,141 個 refs review items 已拆成 4 個真相來源判定、114 個 drift deprecated 候選、3 個 release tag review、20 個 GitHub-only refs review;這是人工判定隊列,不是同步批准。 - 本機可見 Git working tree 輔助盤點已找到 13 個 repo,其中去重後 Gitea repo 4 個、GitHub repo 5 個、110 內部 repo 4 個;此結果可用來補遷移矩陣,但不能取代 Gitea server 全量清單。 因此後續必須先完成「repo/branch/tag/workflow/webhook/permission/secrets 名稱」全量 inventory,再逐步 mirror 與驗證。 @@ -76,6 +78,7 @@ | GitHub target repo-by-repo approval snapshot | `docs/security/github-target-repo-approval-package.snapshot.json`,逐 repo 拆分 approval path,不授權執行 | | Source Control draft reconcile plan | `docs/security/source-control-reconcile-plan.snapshot.json`,只產生 `draft_blocked` 草案,不授權 refs sync | | Source Control branch/tag detail diff | `docs/security/source-control-ref-detail-diff.snapshot.json`,保存 3 個 refs-blocked mapped repos 的 branch/tag 明細,不授權 fetch/push | +| Source Control ref truth classification | `docs/security/source-control-ref-truth-classification.snapshot.json`,將 ref diff 轉成單 ref 人工判定隊列,不授權 sync/delete | ## 1.1 Gitea repo list snapshot @@ -146,7 +149,7 @@ GitHub target repo-by-repo approval package 已建立於 `docs/security/GITHUB-T | 欄位 | Gitea | GitHub | 狀態 | |------|-------|--------|------| | Repo | `wooo/awoooi` | `owenhytsai/awoooi` | 已有對應 | -| `main` | `631fc220c3f50a2b977b9e07cbd4f99c0fccf8d8` | `202071f7a8724d5e8c29de441c3f380575a0ea94` | 不一致,阻塞主控切換 | +| `main` | `5294f0712f1a3370d0155c0d88e5d10c6ec0250e` | `202071f7a8724d5e8c29de441c3f380575a0ea94` | 不一致,阻塞主控切換 | | `release/v1.0` | `d15fb7d9f4bac86873d5c16b9c17c527b8f38bef` | `d15fb7d9f4bac86873d5c16b9c17c527b8f38bef` | 一致 | | `dev` | `25889d4b8edcb83b6ec707c5eef3c21ae5d432b0` | 無 | GitHub 缺分支 | | `drift/adopt-*` | 多條 | 無 | GitHub 缺分支 | @@ -201,7 +204,7 @@ GitHub target repo-by-repo approval package 已建立於 `docs/security/GITHUB-T "branch_count_github": 2, "tag_count_gitea": 2, "tag_count_github": 0, - "latest_sha_gitea": "631fc220c3f50a2b977b9e07cbd4f99c0fccf8d8", + "latest_sha_gitea": "5294f0712f1a3370d0155c0d88e5d10c6ec0250e", "latest_sha_github": "202071f7a8724d5e8c29de441c3f380575a0ea94", "workflows_mapped": false, "webhooks_mapped": false, @@ -217,7 +220,7 @@ GitHub target repo-by-repo approval package 已建立於 `docs/security/GITHUB-T 1. 依 `docs/security/GITEA-READONLY-INVENTORY-APPROVAL-PACKAGE.md` 取得 Gitea 只讀 repo inventory 批准,不使用寫入 token。 2. 依 `github_target_decision_v1` 對需要人工批准的 target 做 owner / visibility / canonical 決策。 -3. 依 `docs/security/SOURCE-CONTROL-RECONCILE-PLAN.md` 產生每個 repo 的 heads/tags SHA diff;仍不 push refs。 +3. 依 `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md` 由 repo owner 對 main/dev、release tags、GitHub-only refs 與 drift deprecated 候選逐項判定;仍不 push refs。 4. 標記「可 mirror」、「需人工判斷」、「需封存」、「不可搬」。 5. 產出 GitHub primary ADR,定義切換 gate 與 rollback。 6. 將 `source_control_migration_event_v1`、`gitea_repo_inventory_v1`、`local_git_remote_inventory_v1` mirror 到 AwoooP,初期只作為 evidence。 diff --git a/docs/security/SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md b/docs/security/SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md index f8e069f0..f9867317 100644 --- a/docs/security/SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md +++ b/docs/security/SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md @@ -2,7 +2,7 @@ | 項目 | 內容 | |------|------| -| 日期 | 2026-05-12 | +| 日期 | 2026-05-13 | | 狀態 | 草案 | | JSON snapshot | `docs/security/security-supply-chain-contract-manifest.snapshot.json` | | Schema | `docs/schemas/security_supply_chain_contract_manifest_v1.schema.json` | @@ -11,7 +11,7 @@ ## 0. 核心結論 -目前 Security Supply Chain 已有 15 個主要契約可交給 AwoooP 消費。Manifest 的用途是把分散的 schema、snapshot、人讀文件、允許動作與禁止動作收成一份入口,避免不同 Session 各自解讀。 +目前 Security Supply Chain 已有 16 個主要契約可交給 AwoooP 消費。Manifest 的用途是把分散的 schema、snapshot、人讀文件、允許動作與禁止動作收成一份入口,避免不同 Session 各自解讀。 初期預設仍是 `mirror_only`。Manifest 不授權 runtime enforcement、不授權 GitHub/Gitea 主控切換、不授權 repo 建立或 refs sync。 @@ -31,6 +31,7 @@ | `source_control_approval_board_v1` | approval-only | 逐 repo owner / visibility / canonical / refs 決策 board | `source-control-approval-board.snapshot.json` | | `source_control_reconcile_plan_v1` | approval-only | refs-blocked repo 的 draft reconcile plan | `source-control-reconcile-plan.snapshot.json` | | `source_control_ref_detail_diff_v1` | mirror-only | refs-blocked repo 的 branch/tag 明細 diff | `source-control-ref-detail-diff.snapshot.json` | +| `source_control_ref_truth_classification_v1` | approval-only | refs diff 的真相來源候選與 deprecated 候選分類 | `source-control-ref-truth-classification.snapshot.json` | | `local_repo_canonical_probe_v1` | mirror-only | momo/ewoooc lineage evidence | `local-repo-canonical-ewoooc-momo.snapshot.json` | | `git_remote_refs_probe_v1` | mirror-only | 110 / GitHub remote refs readiness | `bitan-tsenyang`、`wooo-infra-config` | | `approval_required_event_v1` | approval-only | 高風險 / 敏感邊界 approval | `gitea-readonly-inventory-approval.snapshot.json` | diff --git a/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md b/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md index 86811a25..97cdec28 100644 --- a/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md +++ b/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md @@ -2,9 +2,9 @@ | 項目 | 內容 | |------|------| -| 日期 | 2026-05-12 | +| 日期 | 2026-05-13 | | 狀態 | S0/S1 read-only evidence 建置中 | -| 本階段完成 | Security Supply Chain contract manifest + Source Control Approval Board + Draft Reconcile Plan + Ref Detail Diff | +| 本階段完成 | Security Supply Chain contract manifest + Source Control Approval Board + Draft Reconcile Plan + Ref Detail Diff + Ref Truth Classification | | 原則 | 低摩擦分階段;文件、schema、read-only evidence 優先;不做 runtime enforcement、不切 primary | ## 0. 本階段完成後整體進度 @@ -18,8 +18,9 @@ | S1.2 GitHub target 逐 repo approval | 完成草案 | 7 個 approval-required targets 已拆成逐 repo pending package,並彙整成 8-item approval board | 低摩擦逐項批准 | | S1.2a refs reconcile plan | 完成草案 | `awoooi`、`clawbot-v5`、`wooo-aiops` 已產生 draft plan;狀態仍為 `draft_blocked` | authenticated inventory + branch/tag diff + single-repo approval | | S1.2b branch/tag detail diff | 完成草案 | 3 個 refs-blocked mapped repos 已完成 branch/tag 明細 diff;已忽略本 PR 分支避免 evidence 自我污染 | 人工判定真相來源與 deprecated refs | +| S1.2c refs 真相來源分類 | 完成草案 | 141 個 ref review items 已分類:4 個真相來源、114 個 drift deprecated 候選、3 個 release tags、20 個 GitHub-only refs | repo owner 單 ref / 單 repo 判定 | | S1.3 低摩擦 rollout policy | 完成草案 | observe-first / mirror-only matrix 已建立 | AwoooP read-only policy 消費 | -| S1.4 Contract manifest | 完成草案 | 15 個主要 contract 已集中成 manifest | AwoooP mirror-only contract registry | +| S1.4 Contract manifest | 完成草案 | 16 個主要 contract 已集中成 manifest | AwoooP mirror-only contract registry | | S2 AwoooP mirror-only | 可交接 | `AWOOOP-MIRROR-ONLY-CONSUMPTION-CHECKLIST.md` 已列出可消費事件與禁止動作 | AwoooP 主線建立只讀入口 | | S3 approval gate | 未開始 | 已定義哪些動作要進 approval | 不得繞過人工批准 | | S4 migration execution | 未開始 | GitHub primary 長期方向已確認,但 refs / tags / workflow / secret 名稱尚未全量驗證 | SHA/tag/workflow parity 與 rollback ADR | @@ -48,6 +49,8 @@ | Source Control draft reconcile plan JSON | `docs/security/source-control-reconcile-plan.snapshot.json` | | Source Control branch/tag detail diff | `docs/security/SOURCE-CONTROL-REF-DETAIL-DIFF.md` | | Source Control branch/tag detail diff JSON | `docs/security/source-control-ref-detail-diff.snapshot.json` | +| Source Control ref truth classification | `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md` | +| Source Control ref truth classification JSON | `docs/security/source-control-ref-truth-classification.snapshot.json` | | 低摩擦 rollout policy | `docs/security/SECURITY-LOW-FRICTION-ROLLOUT-POLICY.md` | | 低摩擦 rollout policy JSON | `docs/security/security-rollout-policy.snapshot.json` | | Security Supply Chain contract manifest | `docs/security/SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md` | @@ -74,7 +77,7 @@ 1. 等待 Gitea read-only inventory approval 被批准後,再用只讀 token 或管理匯出補 private/internal server-side 全量 repo list。 2. 依 `SOURCE-CONTROL-APPROVAL-BOARD.md` 對 7 個 `approval_required=true` 的 GitHub target 做 owner / visibility / canonical 決策。 -3. 依 `SOURCE-CONTROL-REF-DETAIL-DIFF.md` 對 `awoooi`、`clawbot-v5`、`wooo-aiops` 標記真相來源候選與 deprecated refs;仍不得 push refs。 +3. 依 `SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md` 對 `awoooi`、`clawbot-v5`、`wooo-aiops` 做單 repo / 單 ref owner 判定;仍不得 push refs。 4. 對 `ewoooc` / `momo-pro-system` 完成 server-side canonical 判定。 5. AwoooP 主線只建立 mirror-only / read-only policy 入口,不新增執行按鈕。 6. AwoooP 主線消費 `security_rollout_policy_v1` 時,只做 read-only policy,不做 runtime blocking。 diff --git a/docs/security/SOURCE-CONTROL-MIGRATION-MATRIX.md b/docs/security/SOURCE-CONTROL-MIGRATION-MATRIX.md index a6a31d5d..0e869007 100644 --- a/docs/security/SOURCE-CONTROL-MIGRATION-MATRIX.md +++ b/docs/security/SOURCE-CONTROL-MIGRATION-MATRIX.md @@ -12,6 +12,7 @@ | GitHub target repo approval | `docs/security/GITHUB-TARGET-REPO-APPROVAL-PACKAGE.md` | | Source Control draft reconcile plan | `docs/security/SOURCE-CONTROL-RECONCILE-PLAN.md` | | Source Control branch/tag detail diff | `docs/security/SOURCE-CONTROL-REF-DETAIL-DIFF.md` | +| Source Control ref truth classification | `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md` | | 原則 | 只做盤點與分類,不做同步、不刪除、不切 primary | ## 0. 核心結論 @@ -119,6 +120,8 @@ GitHub primary 可以作為長期方向,但目前還不能切換。 Repo-by-repo approval package 已建立,7 個 approval-required targets 皆為 `pending`。Approval scope 採低摩擦原則:只處理高風險執行邊界,不阻擋 read-only inventory、evidence mirror 與草案規劃。 +Ref truth classification 已建立,將 `awoooi`、`clawbot-v5`、`wooo-aiops` 的 141 個 refs 差異拆成 review lane。`main` / `dev` 屬真相來源判定,`drift/adopt-*` 先列 deprecated candidate,release / UAT tags 先列保留判定;不得把分類結果直接執行成同步、刪除或 primary switch。 + ## 3. 必要驗收 gate 任何 repo 進入「已可切 GitHub primary」之前,都必須通過: @@ -136,17 +139,19 @@ Repo-by-repo approval package 已建立,7 個 approval-required targets 皆為 | Repo | Status | Gitea branches | GitHub branches | Gitea tags | GitHub tags | Gitea main | GitHub main | Evidence | |------|--------|----------------|-----------------|------------|-------------|------------|-------------|----------| -| `wooo/awoooi` -> `owenhytsai/awoooi` | `blocked` | `117` | `2` | `2` | `0` | `631fc220c3f50a2b977b9e07cbd4f99c0fccf8d8` | `202071f7a8724d5e8c29de441c3f380575a0ea94` | `docs/security/SOURCE-CONTROL-REF-DETAIL-DIFF.md` | +| `wooo/awoooi` -> `owenhytsai/awoooi` | `blocked` | `117` | `2` | `2` | `0` | `5294f0712f1a3370d0155c0d88e5d10c6ec0250e` | `202071f7a8724d5e8c29de441c3f380575a0ea94` | `docs/security/SOURCE-CONTROL-REF-DETAIL-DIFF.md` | | `wooo/clawbot-v5` -> `owenhytsai/clawbot-v5` | `blocked` | `1` | `1` | `1` | `0` | `22074fbe4d6ec6c11c86f76139eea55756d1d160` | `7a769de46450087f9d6a8ef0d2ac23ed15565d2c` | `docs/security/SOURCE-CONTROL-CLAWBOT-V5-SNAPSHOT.md` | | `wooo/wooo-aiops` -> `owenhytsai/wooo-aiops` | `blocked` | `2` | `3` | `0` | `19` | `507384a2e1943f4183942bf17d7b52e223067853` | `7c7aa109d93da6d75d687d6ee5131151afee37e8` | `docs/security/SOURCE-CONTROL-WOOO-AIOPS-SNAPSHOT.md` | 這三個 mapped repos 都不能直接視為 GitHub primary ready。 +Ref truth classification 補充:完整 review lane 見 `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md`。目前分類結果是 4 個 `manual_truth_required`、114 個 `manual_review_deprecated_candidate`、3 個 `manual_review_release_tag`、20 個 `manual_review_github_only`。 + ## 5. 下一波建議 1. 先批准 Gitea read-only inventory package,再用只讀 token 或管理匯出補齊 Gitea server repo list。 2. 依 GitHub target repo-by-repo approval package 處理 7 個 approval-required target。 -3. 釐清 `wooo/awoooi`、`wooo/clawbot-v5`、`wooo/wooo-aiops` 的雙端分歧來源。 +3. 依 ref truth classification 釐清 `wooo/awoooi`、`wooo/clawbot-v5`、`wooo/wooo-aiops` 的雙端分歧來源。 4. 釐清 `wooo/ewoooc`、`root/momo-pro-system`、`momo-pro-system`、`momo_pro_system` 的 canonical 關係。 5. 釐清 `bitan-pharmacy`、`tsenyang-website` 是否仍 active,並決定 GitHub owner / visibility。 6. 產出 GitHub primary ADR 前,不做主控切換。 diff --git a/docs/security/SOURCE-CONTROL-RECONCILE-PLAN.md b/docs/security/SOURCE-CONTROL-RECONCILE-PLAN.md index a213461a..f648082c 100644 --- a/docs/security/SOURCE-CONTROL-RECONCILE-PLAN.md +++ b/docs/security/SOURCE-CONTROL-RECONCILE-PLAN.md @@ -13,11 +13,13 @@ 這份文件只是 refs reconcile 草案,不是同步腳本,也不授權任何 GitHub primary 切換。AwoooP 可以 mirror 成 approval candidate,但不得執行 board item 或呼叫任何 push / sync 工具。 +若已存在 `source_control_ref_truth_classification_v1`,請把它視為本 plan 的人工 review lane 補充:分類結果只協助 repo owner 判定,不授權同步或刪除。 + ## 1. Repo 差異摘要 | Repo | Risk | Gitea branches | GitHub branches | Gitea tags | GitHub tags | Gitea main | GitHub main | |------|------|----------------|-----------------|------------|-------------|------------|-------------| -| `wooo/awoooi -> owenhytsai/awoooi` | `HIGH` | `117` | `2` | `2` | `0` | `631fc220` | `202071f7` | +| `wooo/awoooi -> owenhytsai/awoooi` | `HIGH` | `117` | `2` | `2` | `0` | `5294f071` | `202071f7` | | `wooo/clawbot-v5 -> owenhytsai/clawbot-v5` | `MEDIUM` | `1` | `1` | `1` | `0` | `22074fbe` | `7a769de4` | | `wooo/wooo-aiops -> owenhytsai/wooo-aiops` | `MEDIUM` | `2` | `3` | `0` | `19` | `507384a2` | `7c7aa109` | @@ -135,3 +137,4 @@ 2. 只顯示 `draft_blocked` 與 blocking reason。 3. 可產生 approval candidate,但不得自動批准。 4. 不得新增 execution action button。 +5. 真相來源分類請讀 `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md`,並維持單 repo / 單 ref 人工 gate。 diff --git a/docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md b/docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md new file mode 100644 index 00000000..c246a795 --- /dev/null +++ b/docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md @@ -0,0 +1,135 @@ +# Source Control Ref Truth Classification + +| 項目 | 內容 | +|------|------| +| 日期 | 2026-05-13 | +| 狀態 | `draft_blocked` | +| 預設模式 | `classification_only` | +| 來源 snapshot | `docs/security/source-control-ref-detail-diff.snapshot.json` | +| repo count | `3` | +| total items | `141` | + +## 0. 核心結論 + +本檔把 branch/tag diff 轉成「人工審核分類」:哪些 ref 需要真相來源判定、哪些可能是 deprecated 候選、哪些 release / UAT tags 需要保留判定。它不是同步計畫,也不授權 fetch、push、delete refs 或 GitHub primary 切換。 + +## 1. 摘要 + +| 指標 | 數量 | +|------|------| +| 需要人工指定真相來源 | `4` | +| 可能 deprecated / archive 候選 | `114` | +| release tag 待審核 | `3` | +| GitHub-only ref 待審核 | `20` | + +## 2. Repo 分類 + +### wooo/awoooi -> owenhytsai/awoooi + +- Risk:`HIGH` +- AwoooP consumption:`approval_candidate` +- Item count:`118` + +| Ref | Type | Lane | Classification | Gitea | GitHub | 下一步 | +|-----|------|------|----------------|-------|--------|--------| +| `main` | `branch` | `main_truth_required` | `manual_truth_required` | `5294f071` | `202071f7` | 先確認目前 production deploy 真相來源、deploy marker、rollback 點,再決定單 repo reconcile。 | +| `dev` | `branch` | `active_branch_truth_required` | `manual_truth_required` | `25889d4b` | `無` | 確認 dev 是否仍為有效工作流;若有效,再決定單 branch 同步策略。 | +| `drift/adopt-00e93ec6-20260507202835` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-018dfeb6-20260510201057` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-036399ae-20260512101936` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-036399ae-20260512113011` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-03ab23eb-20260511190611` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-04532fd3-20260509104706` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-094107c8-20260511171658` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-0b67aa5a-20260508132246` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-0d55cf70-20260512152046` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `abdab853` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-0d7e2731-20260422111000` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `75b7d338` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-11d02e8c-20260505000302` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `40badc42` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-18d2841e-20260506203612` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `b2f0db07` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-1941d569-20260509001722` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-1b510a59-20260508071355` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-1d45b689-20260512101956` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-1ffaa1de-20260509191538` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-22d3c494-20260504010134` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `035fe20e` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-256b7b16-20260507082410` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `c52ebfc0` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-2582b60d-20260509160733` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-2b26cfe4-20260509104618` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-3254209e-20260505150522` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d08d1e49` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-3336b941-20260511111108` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-34bf86fd-20260421010616` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `3323a905` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-35e8371b-20260508222338` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-378290ab-20260510201203` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-381202c7-20260507171310` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `afb5f955` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-38e32fb9-20260506171242` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `76aaaf48` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-39383806-20260502230445` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `68e18238` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-3da139d9-20260503161425` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `e45b055e` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-44860c3d-20260510171817` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-46e77bf6-20260506235709` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `012cd27b` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-49920526-20260511111126` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-4b40fc0d-20260429080302` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `20009cdd` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-4d8f3bef-20260508212335` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-4e188293-20260504100431` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `035fe20e` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-4e5775dc-20260510233800` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-50d442fb-20260510201215` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| `drift/adopt-52fb18e5-20260512000119` | `branch` | `archive_or_deprecate_candidate` | `manual_review_deprecated_candidate` | `d356cd32` | `無` | 由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。 | +| 另有 `78` 筆 | | | 完整清單見 JSON snapshot | | | | + +### wooo/clawbot-v5 -> owenhytsai/clawbot-v5 + +- Risk:`MEDIUM` +- AwoooP consumption:`approval_candidate` +- Item count:`2` + +| Ref | Type | Lane | Classification | Gitea | GitHub | 下一步 | +|-----|------|------|----------------|-------|--------|--------| +| `main` | `branch` | `main_truth_required` | `manual_truth_required` | `22074fbe` | `7a769de4` | 先確認目前 production deploy 真相來源、deploy marker、rollback 點,再決定單 repo reconcile。 | +| `v5.5-sprint1` | `tag` | `release_tag_missing_on_github` | `manual_review_release_tag` | `2b126871` | `無` | 確認 tag 對應 release / artifact / deploy marker,再以單 repo approval 決定是否同步。 | + +### wooo/wooo-aiops -> owenhytsai/wooo-aiops + +- Risk:`MEDIUM` +- AwoooP consumption:`approval_candidate` +- Item count:`21` + +| Ref | Type | Lane | Classification | Gitea | GitHub | 下一步 | +|-----|------|------|----------------|-------|--------|--------| +| `main` | `branch` | `main_truth_required` | `manual_truth_required` | `507384a2` | `7c7aa109` | 先確認目前 production deploy 真相來源、deploy marker、rollback 點,再決定單 repo reconcile。 | +| `refactor/phase-9.3` | `branch` | `github_only_manual_review` | `manual_review_github_only` | `無` | `7261f94b` | 確認該 branch 是否為有效 refactor/feature 線,並判定是否回補到 Gitea 或保留 GitHub-only。 | +| `uat-20260316-1ec245f` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `1ec245fd` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260316-2d54a43` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `2d54a43b` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260316-3e8df86` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `3e8df861` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260316-95002f5` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `95002f50` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260316-9ebea63` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `9ebea633` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260316-a851c80` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `a851c809` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260316-e2ee674` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `e2ee6746` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260316-fa48be2` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `fa48be21` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260317-f768051` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `f7680510` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260318-20dde91` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `20dde91a` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260318-4025dde` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `4025dde5` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260318-5bfa151` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `5bfa1514` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260318-663b590` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `663b590d` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260318-78a3757` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `78a3757c` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260318-7c6f666` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `7c6f6665` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260318-c4d5669` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `c4d56690` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260318-cf42fd4` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `cf42fd4e` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260319-7c7aa10` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `7c7aa109` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | +| `uat-20260319-ce5c72b` | `tag` | `github_only_uat_tag` | `manual_review_github_only` | `無` | `ce5c72b5` | 確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。 | + +## 3. AwoooP 消費方式 + +1. 只 mirror `source_control_ref_truth_classification_v1`。 +2. 可顯示 review lane 與 owner decision queue。 +3. 可產生單 repo / 單 ref approval candidate,但不得自動批准。 +4. 不得新增 refs sync、delete、force-push、primary switch action。 + +## 4. 仍然禁止 + +- fetch +- push refs +- force push +- delete refs +- create GitHub repo +- change repo visibility +- switch GitHub primary +- disable Gitea +- move secret values diff --git a/docs/security/security-supply-chain-contract-manifest.snapshot.json b/docs/security/security-supply-chain-contract-manifest.snapshot.json index bf82f0aa..028abf1e 100644 --- a/docs/security/security-supply-chain-contract-manifest.snapshot.json +++ b/docs/security/security-supply-chain-contract-manifest.snapshot.json @@ -2,7 +2,7 @@ "schema_version": "security_supply_chain_contract_manifest_v1", "status": "draft", "default_enforcement_level": "mirror_only", - "contract_count": 15, + "contract_count": 16, "contracts": [ { "contract": "security_rollout_policy_v1", @@ -177,6 +177,26 @@ ], "notes": "只保存 branch/tag 明細 diff;忽略本 PR 分支避免 evidence 自我污染。" }, + { + "contract": "source_control_ref_truth_classification_v1", + "schema_path": "docs/schemas/source_control_ref_truth_classification_v1.schema.json", + "snapshot_paths": ["docs/security/source-control-ref-truth-classification.snapshot.json"], + "human_docs": ["docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md"], + "consumer": "AwoooP migration reviewer / repo owner approval queue", + "consumption_mode": "approval_only", + "allowed_actions": [ + "mirror_ref_truth_classification", + "display_truth_source_candidates", + "request_single_ref_human_review" + ], + "forbidden_actions": [ + "execute_classification", + "push_refs", + "delete_refs", + "switch_github_primary" + ], + "notes": "把 refs diff 分成 main/dev 真相來源、drift deprecated 候選、release tag 與 GitHub-only review lane;仍不授權 sync。" + }, { "contract": "local_repo_canonical_probe_v1", "schema_path": "docs/schemas/local_repo_canonical_probe_v1.schema.json", diff --git a/docs/security/source-control-reconcile-plan.snapshot.json b/docs/security/source-control-reconcile-plan.snapshot.json index 0391ef4c..f0c003ea 100644 --- a/docs/security/source-control-reconcile-plan.snapshot.json +++ b/docs/security/source-control-reconcile-plan.snapshot.json @@ -28,7 +28,7 @@ "github_branch_count": 2, "gitea_tag_count": 2, "github_tag_count": 0, - "gitea_main_sha": "631fc22090ff6b6a26582890b2de0498d118895f", + "gitea_main_sha": "5294f0712f1a3370d0155c0d88e5d10c6ec0250e", "github_main_sha": "202071f7a8724d5e8c29de441c3f380575a0ea94", "blocking_reason": "branches 尚未完全對齊;tags 尚未完全對齊" }, diff --git a/docs/security/source-control-ref-truth-classification.snapshot.json b/docs/security/source-control-ref-truth-classification.snapshot.json new file mode 100644 index 00000000..ff5ed156 --- /dev/null +++ b/docs/security/source-control-ref-truth-classification.snapshot.json @@ -0,0 +1,4144 @@ +{ + "schema_version": "source_control_ref_truth_classification_v1", + "status": "draft_blocked", + "date": "2026-05-13", + "default_mode": "classification_only", + "source_snapshot": "docs/security/source-control-ref-detail-diff.snapshot.json", + "summary": { + "repo_count": 3, + "total_items": 141, + "manual_truth_required_count": 4, + "deprecated_candidate_count": 114, + "release_tag_review_count": 3, + "github_only_review_count": 20 + }, + "still_forbidden": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ], + "repos": [ + { + "gitea_repo": "wooo/awoooi", + "github_repo": "owenhytsai/awoooi", + "risk": "HIGH", + "awooop_consumption": "approval_candidate", + "item_count": 118, + "items": [ + { + "ref_type": "branch", + "ref_name": "main", + "lane": "main_truth_required", + "risk": "HIGH", + "proposed_truth_source": "manual_required", + "classification": "manual_truth_required", + "reason": "兩端 main SHA 不一致,這是 GitHub primary / deploy control plane 的硬阻塞。", + "next_review": "先確認目前 production deploy 真相來源、deploy marker、rollback 點,再決定單 repo reconcile。", + "gitea_sha": "5294f0712f1a3370d0155c0d88e5d10c6ec0250e", + "github_sha": "202071f7a8724d5e8c29de441c3f380575a0ea94", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "dev", + "lane": "active_branch_truth_required", + "risk": "HIGH", + "proposed_truth_source": "manual_required", + "classification": "manual_truth_required", + "reason": "`dev` 可能是仍在使用的開發分支,GitHub 缺少此 ref 前不得判定 GitHub ready。", + "next_review": "確認 dev 是否仍為有效工作流;若有效,再決定單 branch 同步策略。", + "gitea_sha": "25889d4b8edcb83b6ec707c5eef3c21ae5d432b0", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-00e93ec6-20260507202835", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-018dfeb6-20260510201057", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-036399ae-20260512101936", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-036399ae-20260512113011", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-03ab23eb-20260511190611", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-04532fd3-20260509104706", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-094107c8-20260511171658", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-0b67aa5a-20260508132246", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-0d55cf70-20260512152046", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "abdab85362c577bd734ab1c7796bb6f33f070eca", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-0d7e2731-20260422111000", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "75b7d338e0003311c63f5fd81f9c81e2ebe41f7b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-11d02e8c-20260505000302", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "40badc42cf81b1f8193bee2221d46ec5b52de6dd", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-18d2841e-20260506203612", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "b2f0db07178c7469ccaa1d1644fcdadaf044bfcb", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-1941d569-20260509001722", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-1b510a59-20260508071355", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-1d45b689-20260512101956", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-1ffaa1de-20260509191538", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-22d3c494-20260504010134", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "035fe20e4d5b7564a68c22d82c56dca266009bd7", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-256b7b16-20260507082410", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "c52ebfc0423bea993fdc21dd205f78d2262a660e", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-2582b60d-20260509160733", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-2b26cfe4-20260509104618", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-3254209e-20260505150522", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d08d1e49518fcf57abce7bda10554adbcba395cc", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-3336b941-20260511111108", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-34bf86fd-20260421010616", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "3323a9052c95a81e645fbf3c78c87ee9e2b16d6b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-35e8371b-20260508222338", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-378290ab-20260510201203", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-381202c7-20260507171310", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "afb5f9556e74eeced130cf0e67029d9c85b48c1a", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-38e32fb9-20260506171242", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "76aaaf480c08beb9d5d4c880a8fe850fd84c5ce0", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-39383806-20260502230445", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "68e182381f37dc45d99744c24a518d47c859540f", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-3da139d9-20260503161425", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "e45b055e0e3ea25afbbb45c4f477a632a8945c54", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-44860c3d-20260510171817", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-46e77bf6-20260506235709", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "012cd27b4a27065e40a33728f8095e933114c27b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-49920526-20260511111126", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-4b40fc0d-20260429080302", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "20009cddcf392fde3423680069b2322604a31cf5", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-4d8f3bef-20260508212335", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-4e188293-20260504100431", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "035fe20e4d5b7564a68c22d82c56dca266009bd7", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-4e5775dc-20260510233800", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-50d442fb-20260510201215", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-52fb18e5-20260512000119", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-55aaa7de-20260512151737", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "abdab85362c577bd734ab1c7796bb6f33f070eca", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-567cd7c0-20260511132950", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-5bc6628e-20260512113026", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-60b714c6-20260504131233", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "b4055c5915bfcf8f6a37f9656be291ebe7fc526c", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-60c4401c-20260510201228", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-629f415a-20260504110028", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "f7e5fc772e6f25d7f9a69374a2bdd9febccccf87", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-636e7a0a-20260508150402", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-6384c896-20260510201239", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-67e03b24-20260510194653", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-6857ca25-20260508105853", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-699b4785-20260506160255", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "927c2a758dd748d4cac084dc7850059952b02353", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-6beac0f6-20260425192742", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "4a8c3ca5c4a5c80f4d75dac4acb54e74dbb71bfe", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-6c17ef6d-20260509191548", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-6d4dcbb6-20260421230348", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "49e465954cbe8f552b440b78c76b235d5f8ff14c", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-6e7ec67f-20260504120519", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "b4055c5915bfcf8f6a37f9656be291ebe7fc526c", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-6fae380e-20260422102753", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "75b7d338e0003311c63f5fd81f9c81e2ebe41f7b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-6fb9a504-20260507202914", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-7018530f-20260512113057", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-732ed7e5-20260511150635", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-7517bc64-20260509125450", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-7551fb42-20260424144550", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "9793f7f5edaff9c9ac199ab34053831534544635", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-75f11639-20260508212322", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-767d3213-20260512000035", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-777008e2-20260510233821", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-7912a251-20260508181656", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-7dddec5a-20260508230651", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-7e701601-20260508140947", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-7f3a03db-20260512112944", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-7fbb45c2-20260506081629", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "df5e6c66263884eb9d6f510853e1f5144de3b9ec", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-8293df04-20260510201332", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-8360b6c9-20260507082544", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "c52ebfc0423bea993fdc21dd205f78d2262a660e", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-84e9fc38-20260507082618", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "c52ebfc0423bea993fdc21dd205f78d2262a660e", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-8eb798d0-20260503020341", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "0f009d94590d0545bc681682b2ca5b1980539ce7", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-8f0c2384-20260509132348", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-8f29634d-20260510223341", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-8f8e1f11-20260507082638", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "c52ebfc0423bea993fdc21dd205f78d2262a660e", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-92789f1e-20260512181538", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "a18e2f9c3f403050d0fb7476bf6fdb860225731a", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-94ed08b7-20260510201336", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-95e3318c-20260510194637", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-96153b22-20260509171850", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-97554a3d-20260507130220", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "c88d82f2acec52032de658d732ef314d9dd3331d", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-978af647-20260507021159", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "3f69e03fcb915514aabf25263b5004b7de5912dc", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-9959a942-20260423232150", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "9793f7f5edaff9c9ac199ab34053831534544635", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-99d4bd24-20260512000050", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-9d6a34ed-20260511111155", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-9e72bfe1-20260512160042", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "6b02f49fc64f2ba6d55166d0517894ab2f6253a3", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-a72c3cd5-20260502225149", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "68e182381f37dc45d99744c24a518d47c859540f", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-a979c86e-20260506140947", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "578bf3bc7ce495a80752e7124c005b64c6943ead", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-aadf7da2-20260512101903", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-ac03f7a1-20260509104658", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-af72d85c-20260425140126", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "4a8c3ca5c4a5c80f4d75dac4acb54e74dbb71bfe", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-b3dbf399-20260512113118", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-b75fe78c-20260508105822", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-b8cf88fc-20260512113132", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-b9320b66-20260511001336", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-bd499c90-20260506191626", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d90414ddfa863443927d663a13140bf7e089d0c4", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-c6231f70-20260512181458", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "a18e2f9c3f403050d0fb7476bf6fdb860225731a", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-c68af767-20260512101909", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-c9eebf3d-20260502210402", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "68e182381f37dc45d99744c24a518d47c859540f", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-cd357cc7-20260507130241", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "c88d82f2acec52032de658d732ef314d9dd3331d", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-cdcb477f-20260508212328", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-d01dab15-20260508105747", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-d55fd9d6-20260508132237", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-de6bc318-20260510201129", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-e31f120f-20260511120033", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-e46ff8f0-20260511111140", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-e56ef1bf-20260507113021", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "c88d82f2acec52032de658d732ef314d9dd3331d", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-e75a0bc0-20260510201400", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-ed7621f5-20260504001046", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "035fe20e4d5b7564a68c22d82c56dca266009bd7", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-ee276030-20260422124713", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "9793f7f5edaff9c9ac199ab34053831534544635", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-ef9d03b0-20260505130426", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "0ebd0d8a920e2217785e841b92c66b9fc8ad1ccc", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-efca2ad0-20260510201505", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-f0c35f7a-20260508110913", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-f40987d5-20260509125434", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "d356cd32fcfff2f9c9dbcc489402997153f8d54b", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-f6372f90-20260507082708", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "c52ebfc0423bea993fdc21dd205f78d2262a660e", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "drift/adopt-ffb724f1-20260503190044", + "lane": "archive_or_deprecate_candidate", + "risk": "LOW", + "proposed_truth_source": "deprecated_candidate", + "classification": "manual_review_deprecated_candidate", + "reason": "drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + "next_review": "由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + "gitea_sha": "e45b055e0e3ea25afbbb45c4f477a632a8945c54", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "v7.2.0", + "lane": "release_tag_missing_on_github", + "risk": "HIGH", + "proposed_truth_source": "manual_required", + "classification": "manual_review_release_tag", + "reason": "Gitea-only release tag 可能是正式版本證據;GitHub primary 前需確認是否補 tag。", + "next_review": "確認 tag 對應 release / artifact / deploy marker,再以單 repo approval 決定是否同步。", + "gitea_sha": "898145d68e4e78db4876f8b8e5ae1892986525ff", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "v7.3.0", + "lane": "release_tag_missing_on_github", + "risk": "HIGH", + "proposed_truth_source": "manual_required", + "classification": "manual_review_release_tag", + "reason": "Gitea-only release tag 可能是正式版本證據;GitHub primary 前需確認是否補 tag。", + "next_review": "確認 tag 對應 release / artifact / deploy marker,再以單 repo approval 決定是否同步。", + "gitea_sha": "4b8be32610eaeaa5cff9b94d6d0312d90714b6c7", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + } + ] + }, + { + "gitea_repo": "wooo/clawbot-v5", + "github_repo": "owenhytsai/clawbot-v5", + "risk": "MEDIUM", + "awooop_consumption": "approval_candidate", + "item_count": 2, + "items": [ + { + "ref_type": "branch", + "ref_name": "main", + "lane": "main_truth_required", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_truth_required", + "reason": "兩端 main SHA 不一致,這是 GitHub primary / deploy control plane 的硬阻塞。", + "next_review": "先確認目前 production deploy 真相來源、deploy marker、rollback 點,再決定單 repo reconcile。", + "gitea_sha": "22074fbe4d6ec6c11c86f76139eea55756d1d160", + "github_sha": "7a769de46450087f9d6a8ef0d2ac23ed15565d2c", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "v5.5-sprint1", + "lane": "release_tag_missing_on_github", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_release_tag", + "reason": "Gitea-only release tag 可能是正式版本證據;GitHub primary 前需確認是否補 tag。", + "next_review": "確認 tag 對應 release / artifact / deploy marker,再以單 repo approval 決定是否同步。", + "gitea_sha": "2b12687133db6253503cf0d2c12aff67aa92b899", + "github_sha": "", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + } + ] + }, + { + "gitea_repo": "wooo/wooo-aiops", + "github_repo": "owenhytsai/wooo-aiops", + "risk": "MEDIUM", + "awooop_consumption": "approval_candidate", + "item_count": 21, + "items": [ + { + "ref_type": "branch", + "ref_name": "main", + "lane": "main_truth_required", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_truth_required", + "reason": "兩端 main SHA 不一致,這是 GitHub primary / deploy control plane 的硬阻塞。", + "next_review": "先確認目前 production deploy 真相來源、deploy marker、rollback 點,再決定單 repo reconcile。", + "gitea_sha": "507384a2e1943f4183942bf17d7b52e223067853", + "github_sha": "7c7aa109d93da6d75d687d6ee5131151afee37e8", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "branch", + "ref_name": "refactor/phase-9.3", + "lane": "github_only_manual_review", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only branch 可能代表 GitHub 端曾有獨立工作,不能用 Gitea 覆蓋或刪除。", + "next_review": "確認該 branch 是否為有效 refactor/feature 線,並判定是否回補到 Gitea 或保留 GitHub-only。", + "gitea_sha": "", + "github_sha": "7261f94b86346fb706eca729c5db844e65bd902c", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260316-1ec245f", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "1ec245fd4d90ed6db479b3fb0487545dfd632411", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260316-2d54a43", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "2d54a43b451ce39ab2df6080588f5361864b3a8d", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260316-3e8df86", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "3e8df8615c483702cb4f60f184c2410f12306f1c", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260316-95002f5", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "95002f50a16bab91fd9ccc2ebf578ce7d3cbed77", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260316-9ebea63", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "9ebea633d2d5370634f90130a258e736ca329279", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260316-a851c80", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "a851c80906c9bd933b2160bc6215609367dae57f", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260316-e2ee674", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "e2ee6746da08f9071db8fa320c4c77249c8a31d3", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260316-fa48be2", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "fa48be21dfab84842b5c4f59831f17187d4643ea", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260317-f768051", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "f768051007085517d3e13dcd7cadedfb84bfbd50", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260318-20dde91", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "20dde91a9fab4385d1b9327f8a07f518f6c5bdc6", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260318-4025dde", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "4025dde5927ae22e5cae289191e2422ac02a1f62", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260318-5bfa151", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "5bfa15148417ef89b135b0bd25c5bf8e4493a337", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260318-663b590", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "663b590df4c3c6924abc9b9274042afe3a38a968", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260318-78a3757", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "78a3757cf7edf454d5721185344c476c7842b0a1", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260318-7c6f666", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "7c6f66655e1faa6024f8549a741bdb964f76fdb1", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260318-c4d5669", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "c4d56690f7c480e6ad1ef96dfa5bf90e9b7cc84f", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260318-cf42fd4", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "cf42fd4eee5b10fac7248dc70de26cfd619191ca", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260319-7c7aa10", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "7c7aa109d93da6d75d687d6ee5131151afee37e8", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + }, + { + "ref_type": "tag", + "ref_name": "uat-20260319-ce5c72b", + "lane": "github_only_uat_tag", + "risk": "MEDIUM", + "proposed_truth_source": "manual_required", + "classification": "manual_review_github_only", + "reason": "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。", + "next_review": "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。", + "gitea_sha": "", + "github_sha": "ce5c72b54d6e6d8e96e983d9f80ebd834683a288", + "allowed_now": [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence" + ], + "forbidden_actions": [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values" + ] + } + ] + } + ] +} diff --git a/scripts/security/source-control-reconcile-plan.py b/scripts/security/source-control-reconcile-plan.py index fb598f7a..f45a229d 100644 --- a/scripts/security/source-control-reconcile-plan.py +++ b/scripts/security/source-control-reconcile-plan.py @@ -180,6 +180,8 @@ def write_markdown(plan: dict[str, Any], path: Path) -> None: "", "這份文件只是 refs reconcile 草案,不是同步腳本,也不授權任何 GitHub primary 切換。AwoooP 可以 mirror 成 approval candidate,但不得執行 board item 或呼叫任何 push / sync 工具。", "", + "若已存在 `source_control_ref_truth_classification_v1`,請把它視為本 plan 的人工 review lane 補充:分類結果只協助 repo owner 判定,不授權同步或刪除。", + "", "## 1. Repo 差異摘要", "", "| Repo | Risk | Gitea branches | GitHub branches | Gitea tags | GitHub tags | Gitea main | GitHub main |", @@ -240,6 +242,7 @@ def write_markdown(plan: dict[str, Any], path: Path) -> None: "2. 只顯示 `draft_blocked` 與 blocking reason。", "3. 可產生 approval candidate,但不得自動批准。", "4. 不得新增 execution action button。", + "5. 真相來源分類請讀 `docs/security/SOURCE-CONTROL-REF-TRUTH-CLASSIFICATION.md`,並維持單 repo / 單 ref 人工 gate。", "", ] ) diff --git a/scripts/security/source-control-ref-truth-classification.py b/scripts/security/source-control-ref-truth-classification.py new file mode 100644 index 00000000..43ff8f60 --- /dev/null +++ b/scripts/security/source-control-ref-truth-classification.py @@ -0,0 +1,371 @@ +#!/usr/bin/env python3 +"""把 branch/tag read-only diff 轉成真相來源分類草案。 + +此工具只讀取已脫敏的 ref detail diff snapshot,不呼叫遠端 Git、不 fetch、 +不 push、不刪 branch/tag。輸出用途是人工 review 與 AwoooP mirror。 +""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Any + + +DEFAULT_STILL_FORBIDDEN = [ + "fetch", + "push refs", + "force push", + "delete refs", + "create GitHub repo", + "change repo visibility", + "switch GitHub primary", + "disable Gitea", + "move secret values", +] + +DEFAULT_ALLOWED_NOW = [ + "mirror_classification", + "display_review_lane", + "request_single_ref_owner_decision", + "update_read_only_evidence", +] + + +def load_json(path: Path) -> dict[str, Any]: + return json.loads(path.read_text(encoding="utf-8")) + + +def risk_for_repo(gitea_repo: str) -> str: + if gitea_repo == "wooo/awoooi": + return "HIGH" + return "MEDIUM" + + +def short_sha(value: str) -> str: + return value[:8] if value else "無" + + +def classification_item( + *, + ref_type: str, + ref_name: str, + lane: str, + risk: str, + proposed_truth_source: str, + classification: str, + reason: str, + next_review: str, + gitea_sha: str = "", + github_sha: str = "", +) -> dict[str, Any]: + return { + "ref_type": ref_type, + "ref_name": ref_name, + "lane": lane, + "risk": risk, + "proposed_truth_source": proposed_truth_source, + "classification": classification, + "reason": reason, + "next_review": next_review, + "gitea_sha": gitea_sha, + "github_sha": github_sha, + "allowed_now": DEFAULT_ALLOWED_NOW, + "forbidden_actions": DEFAULT_STILL_FORBIDDEN, + } + + +def classify_branch_only_gitea(item: dict[str, str], repo_risk: str) -> dict[str, Any]: + name = item["name"] + sha = item["sha"] + if name.startswith("drift/adopt-"): + return classification_item( + ref_type="branch", + ref_name=name, + lane="archive_or_deprecate_candidate", + risk="LOW", + proposed_truth_source="deprecated_candidate", + classification="manual_review_deprecated_candidate", + reason="drift/adopt 類分支疑似為漂移承接或暫存分支,先標為可能封存/降級候選,但不得自動刪除。", + next_review="由 repo owner 確認是否仍有部署、PR、回滾或稽核用途;確認前保留。", + gitea_sha=sha, + ) + if name == "dev": + return classification_item( + ref_type="branch", + ref_name=name, + lane="active_branch_truth_required", + risk=repo_risk, + proposed_truth_source="manual_required", + classification="manual_truth_required", + reason="`dev` 可能是仍在使用的開發分支,GitHub 缺少此 ref 前不得判定 GitHub ready。", + next_review="確認 dev 是否仍為有效工作流;若有效,再決定單 branch 同步策略。", + gitea_sha=sha, + ) + return classification_item( + ref_type="branch", + ref_name=name, + lane="manual_review", + risk=repo_risk, + proposed_truth_source="manual_required", + classification="manual_review", + reason="此 Gitea-only branch 不符合已知低風險規則,需要人工判定用途。", + next_review="確認 ref owner、是否 active、是否需保留到 GitHub 或改列封存。", + gitea_sha=sha, + ) + + +def classify_branch_only_github(item: dict[str, str], repo_risk: str) -> dict[str, Any]: + name = item["name"] + return classification_item( + ref_type="branch", + ref_name=name, + lane="github_only_manual_review", + risk=repo_risk, + proposed_truth_source="manual_required", + classification="manual_review_github_only", + reason="GitHub-only branch 可能代表 GitHub 端曾有獨立工作,不能用 Gitea 覆蓋或刪除。", + next_review="確認該 branch 是否為有效 refactor/feature 線,並判定是否回補到 Gitea 或保留 GitHub-only。", + github_sha=item["sha"], + ) + + +def classify_tag_only_gitea(item: dict[str, str], repo_risk: str) -> dict[str, Any]: + return classification_item( + ref_type="tag", + ref_name=item["name"], + lane="release_tag_missing_on_github", + risk=repo_risk, + proposed_truth_source="manual_required", + classification="manual_review_release_tag", + reason="Gitea-only release tag 可能是正式版本證據;GitHub primary 前需確認是否補 tag。", + next_review="確認 tag 對應 release / artifact / deploy marker,再以單 repo approval 決定是否同步。", + gitea_sha=item["sha"], + ) + + +def classify_tag_only_github(item: dict[str, str], repo_risk: str) -> dict[str, Any]: + name = item["name"] + if name.startswith("uat-"): + lane = "github_only_uat_tag" + reason = "GitHub-only UAT tag 可能是舊驗收或臨時發布標記,不得自動刪除或搬回 Gitea。" + next_review = "確認 UAT tag 是否仍需保留為稽核 evidence;若已過期,再列入封存決策。" + else: + lane = "github_only_manual_review" + reason = "GitHub-only tag 可能代表 GitHub 端 release evidence,需要人工判定。" + next_review = "確認 tag owner、release 用途與是否需要與 Gitea 對齊。" + return classification_item( + ref_type="tag", + ref_name=name, + lane=lane, + risk=repo_risk, + proposed_truth_source="manual_required", + classification="manual_review_github_only", + reason=reason, + next_review=next_review, + github_sha=item["sha"], + ) + + +def classify_main_mismatch(item: dict[str, str], repo_risk: str) -> dict[str, Any]: + return classification_item( + ref_type="branch", + ref_name=item["name"], + lane="main_truth_required", + risk=repo_risk, + proposed_truth_source="manual_required", + classification="manual_truth_required", + reason="兩端 main SHA 不一致,這是 GitHub primary / deploy control plane 的硬阻塞。", + next_review="先確認目前 production deploy 真相來源、deploy marker、rollback 點,再決定單 repo reconcile。", + gitea_sha=item["gitea_sha"], + github_sha=item["github_sha"], + ) + + +def classify_repo(repo: dict[str, Any]) -> dict[str, Any]: + repo_risk = risk_for_repo(str(repo["gitea_repo"])) + items: list[dict[str, Any]] = [] + branch = repo["branch_diff"] + tag = repo["tag_diff"] + + for mismatch in branch["sha_mismatch"]: + if mismatch["name"] == "main": + items.append(classify_main_mismatch(mismatch, repo_risk)) + else: + items.append( + classification_item( + ref_type="branch", + ref_name=mismatch["name"], + lane="manual_review", + risk=repo_risk, + proposed_truth_source="manual_required", + classification="manual_truth_required", + reason="Branch 兩端皆存在但 SHA 不一致,需要人工判定哪一端為真相來源。", + next_review="確認是否 active、是否有 PR / deploy / rollback 依賴,再進單 branch reconcile。", + gitea_sha=mismatch["gitea_sha"], + github_sha=mismatch["github_sha"], + ) + ) + + for item in branch["only_gitea"]: + items.append(classify_branch_only_gitea(item, repo_risk)) + for item in branch["only_github"]: + items.append(classify_branch_only_github(item, repo_risk)) + for item in tag["only_gitea"]: + items.append(classify_tag_only_gitea(item, repo_risk)) + for item in tag["only_github"]: + items.append(classify_tag_only_github(item, repo_risk)) + + return { + "gitea_repo": repo["gitea_repo"], + "github_repo": repo["github_repo"], + "risk": repo_risk, + "awooop_consumption": "approval_candidate", + "item_count": len(items), + "items": items, + } + + +def build_snapshot(args: argparse.Namespace) -> dict[str, Any]: + source_path = Path(args.source_snapshot) + source = load_json(source_path) + repos = [classify_repo(repo) for repo in source["repos"]] + all_items = [item for repo in repos for item in repo["items"]] + return { + "schema_version": "source_control_ref_truth_classification_v1", + "status": "draft_blocked", + "date": args.date, + "default_mode": "classification_only", + "source_snapshot": str(source_path), + "summary": { + "repo_count": len(repos), + "total_items": len(all_items), + "manual_truth_required_count": sum( + 1 for item in all_items if item["classification"] == "manual_truth_required" + ), + "deprecated_candidate_count": sum( + 1 for item in all_items if item["classification"] == "manual_review_deprecated_candidate" + ), + "release_tag_review_count": sum( + 1 for item in all_items if item["classification"] == "manual_review_release_tag" + ), + "github_only_review_count": sum( + 1 for item in all_items if item["classification"] == "manual_review_github_only" + ), + }, + "still_forbidden": DEFAULT_STILL_FORBIDDEN, + "repos": repos, + } + + +def write_markdown(snapshot: dict[str, Any], path: Path, *, list_limit: int) -> None: + summary = snapshot["summary"] + lines = [ + "# Source Control Ref Truth Classification", + "", + "| 項目 | 內容 |", + "|------|------|", + f"| 日期 | {snapshot['date']} |", + f"| 狀態 | `{snapshot['status']}` |", + f"| 預設模式 | `{snapshot['default_mode']}` |", + f"| 來源 snapshot | `{snapshot['source_snapshot']}` |", + f"| repo count | `{summary['repo_count']}` |", + f"| total items | `{summary['total_items']}` |", + "", + "## 0. 核心結論", + "", + "本檔把 branch/tag diff 轉成「人工審核分類」:哪些 ref 需要真相來源判定、哪些可能是 deprecated 候選、哪些 release / UAT tags 需要保留判定。它不是同步計畫,也不授權 fetch、push、delete refs 或 GitHub primary 切換。", + "", + "## 1. 摘要", + "", + "| 指標 | 數量 |", + "|------|------|", + f"| 需要人工指定真相來源 | `{summary['manual_truth_required_count']}` |", + f"| 可能 deprecated / archive 候選 | `{summary['deprecated_candidate_count']}` |", + f"| release tag 待審核 | `{summary['release_tag_review_count']}` |", + f"| GitHub-only ref 待審核 | `{summary['github_only_review_count']}` |", + "", + "## 2. Repo 分類", + "", + ] + + for repo in snapshot["repos"]: + lines.extend( + [ + f"### {repo['gitea_repo']} -> {repo['github_repo']}", + "", + f"- Risk:`{repo['risk']}`", + f"- AwoooP consumption:`{repo['awooop_consumption']}`", + f"- Item count:`{repo['item_count']}`", + "", + "| Ref | Type | Lane | Classification | Gitea | GitHub | 下一步 |", + "|-----|------|------|----------------|-------|--------|--------|", + ] + ) + visible_items = repo["items"] if list_limit <= 0 else repo["items"][:list_limit] + for item in visible_items: + lines.append( + "| " + + " | ".join( + [ + f"`{item['ref_name']}`", + f"`{item['ref_type']}`", + f"`{item['lane']}`", + f"`{item['classification']}`", + f"`{short_sha(item['gitea_sha'])}`", + f"`{short_sha(item['github_sha'])}`", + item["next_review"], + ] + ) + + " |" + ) + if list_limit > 0 and repo["item_count"] > list_limit: + lines.append( + f"| 另有 `{repo['item_count'] - list_limit}` 筆 | | | 完整清單見 JSON snapshot | | | |" + ) + lines.append("") + + lines.extend( + [ + "## 3. AwoooP 消費方式", + "", + "1. 只 mirror `source_control_ref_truth_classification_v1`。", + "2. 可顯示 review lane 與 owner decision queue。", + "3. 可產生單 repo / 單 ref approval candidate,但不得自動批准。", + "4. 不得新增 refs sync、delete、force-push、primary switch action。", + "", + "## 4. 仍然禁止", + "", + ] + ) + for value in snapshot["still_forbidden"]: + lines.append(f"- {value}") + lines.append("") + path.write_text("\n".join(lines), encoding="utf-8") + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--date", required=True) + parser.add_argument("--source-snapshot", required=True) + parser.add_argument("--output-json", required=True) + parser.add_argument("--output-md", required=True) + parser.add_argument("--md-list-limit", type=int, default=40) + args = parser.parse_args() + + snapshot = build_snapshot(args) + Path(args.output_json).write_text( + json.dumps(snapshot, ensure_ascii=False, indent=2) + "\n", + encoding="utf-8", + ) + write_markdown(snapshot, Path(args.output_md), list_limit=args.md_list_limit) + print( + "OK source-control ref truth classification " + f"repos={snapshot['summary']['repo_count']} items={snapshot['summary']['total_items']}" + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())