# Gitea Server-side 全量 Repo Inventory Runbook

| 項目 | 內容 |
|------|------|
| 日期 | 2026-06-04 |
| 狀態 | read-only / export-only；P1-2 交接封套已整理 |
| 工具 | `scripts/security/gitea-repo-inventory.py` |
| 事件 | `gitea_repo_inventory_v1` |
| Approval package | `docs/security/GITEA-READONLY-INVENTORY-APPROVAL-PACKAGE.md` |
| Redaction checklist | `docs/security/GITEA-ADMIN-EXPORT-REDACTION-CHECKLIST.md` |
| S4.5 export request | `docs/security/GITEA-AUTHENTICATED-INVENTORY-EXPORT-REQUEST.md` |
| S4.6 import acceptance | `docs/security/GITEA-AUTHENTICATED-INVENTORY-IMPORT-ACCEPTANCE.md` |
| S4.7 coverage attestation | `docs/security/GITEA-INVENTORY-COVERAGE-ATTESTATION.md` |
| S4.9 owner response request packet / 收件包 | `docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-RESPONSE.md` |
| P1-2 request handoff | `docs/security/GITEA-AUTHENTICATED-INVENTORY-EXPORT-REQUEST.md` |
| 原則 | 不寫入 Gitea、不搬 secret value、不建立或刪除 repo |

## 0. 核心結論

目前已確認 `wooo` 在 Gitea 上以 user endpoint 可讀到 2 個 public repos：

1. `wooo/awoooi`
2. `wooo/ewoooc`

但未提供只讀 token 時，這只能代表 public-only 可見範圍，不等同完整 server-side repo list。要滿足「Gitea 目前所有專案版本都轉移到 GitHub」，仍需要下列其中一種來源：

1. Gitea 只讀 token。
2. Gitea 管理介面匯出的 repo list JSON。
3. 由管理者在 Gitea 主機上產出的只含 repo metadata 的脫敏 JSON。

補充：`orgs/wooo/repos` 未認證查詢目前回 404，已保留於 `docs/security/GITEA-ORG-REPO-INVENTORY-BLOCKED-SNAPSHOT.md`。後續若確認 `wooo` 是 org 而非 user，應改用只讀 token 或管理匯出重新驗證。

上述兩條非 public-only 路徑都必須先走 `docs/security/GITEA-READONLY-INVENTORY-APPROVAL-PACKAGE.md`，不得在對話、文件或 LOGBOOK 中保存 token value。

S4.5 已補 `gitea_authenticated_inventory_export_request_v1`：正式要求 authenticated inventory 或 admin export 必須解釋 public-only 2 個 repos 與本機 Gitea remote 4 個 unique repos 的 coverage gap，且輸出仍只能是 `gitea_repo_inventory_v1.status=ok` evidence。

S4.6 已補 `gitea_authenticated_inventory_import_acceptance_v1`：收到 owner / 管理者提供的脫敏 payload 後，必須先依 S4.6 檢查 schema、URL 脫敏、coverage gap、redaction attestation 與敏感值隔離。此驗收仍不授權 repo 建立、refs sync 或 GitHub primary cutover。

S4.7 已補 `gitea_inventory_coverage_attestation_v1`：owner 必須先對 public-only / local remote gap、org/user endpoint、110 internal adjacent source、canonical owner 與 legacy/inaccessible repo disposition 作 scope decision。此 attestation 仍不授權 token 收集、repo 寫入、refs sync 或 primary cutover。

S4.9 已補 `gitea_inventory_owner_attestation_response_v1`：AwoooP 可先顯示 1 個 owner response request packet、5 個 template statuses、3 個 audit event templates、5 個 redaction examples 與 8 個 display sections，並用 6 個 collection checks 維持 request / received / accepted 分離；audit event templates 目前全為 `template_only_not_emitted`、0 emitted，只定義 request shown / response received metadata / outcome classified 的脫敏 metadata 欄位；redaction examples 只供 owner 參考安全回覆形狀；display sections 只固定只讀 UI 區塊順序；owner response 必須依 5 個 template 填寫，並先通過 6 個 intake preflight checks、5 個 outcome lanes 與基本驗收，才能把 S4.7 coverage attestation 視為可審 evidence。此 request packet / response 收件包仍不授權 read-only inventory runtime、repo migration、audit production ingestion 或 primary cutover。

2026-06-04 P1-2 已補 request handoff package：Gitea authenticated inventory request 必須先保留 S4.9 owner response gate 作為先行條件，並將只讀 token API 清冊與 redacted admin export 清冊兩條路徑拆開。交接包只要求 repo metadata、redacted URL、visibility scope、coverage notes 與 evidence refs；token value、write credential、DB dump、repo archive、git object pack、deploy key private key、webhook secret 與 runner registration token 全部拒收。此 handoff 只代表請求包可交接，不代表 payload received / accepted、inventory imported、status=ok、GitHub primary 或 runtime 授權。

## 1. Public-only 快照指令

```bash
python3 scripts/security/gitea-repo-inventory.py \
  --base-url http://192.168.0.110:3001 \
  --org wooo \
  --scope user \
  --github-owner owenhytsai \
  --output-json docs/security/gitea-repo-inventory.snapshot.json \
  --output-md docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md
```

預期狀態：`partial`。

## 2. 只讀 token 快照指令

執行前必須先取得 `approval_required_event_v1` 批准。

```bash
python3 scripts/security/gitea-repo-inventory.py \
  --base-url http://192.168.0.110:3001 \
  --org wooo \
  --scope user \
  --token-env GITEA_READONLY_TOKEN \
  --github-owner owenhytsai \
  --output-json docs/security/gitea-repo-inventory.snapshot.json \
  --output-md docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md
```

注意：

1. 執行前由操作者在安全 shell 內設定 `GITEA_READONLY_TOKEN`，不要把值貼入文件或 shell history。
2. 輸出只保存 `token_present=true`，不保存 token value。
3. 若 token 有權限讀 private/internal repos，狀態才可視為 `ok`。

## 3. 管理匯出 JSON 格式

工具接受以下三種結構：

```json
[
  {
    "full_name": "wooo/example",
    "name": "example",
    "owner": {
      "login": "wooo"
    },
    "private": true,
    "archived": false,
    "empty": false,
    "default_branch": "main",
    "clone_url": "http://192.168.0.110:3001/wooo/example.git",
    "ssh_url": "git@192.168.0.110:wooo/example.git"
  }
]
```

也接受：

```json
{
  "repos": []
}
```

或：

```json
{
  "repositories": []
}
```

## 4. 管理匯入指令

匯入前必須先確認 JSON 已 redacted，不含 token、password、webhook secret、deploy key private key 或 repository secret value。
詳細檢查表見 `docs/security/GITEA-ADMIN-EXPORT-REDACTION-CHECKLIST.md`。

```bash
python3 scripts/security/gitea-repo-inventory.py \
  --base-url http://192.168.0.110:3001 \
  --org wooo \
  --github-owner owenhytsai \
  --input-json /path/to/redacted-gitea-repos.json \
  --output-json docs/security/gitea-repo-inventory.snapshot.json \
  --output-md docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md
```

預期狀態：`ok`，且 `visibility_scope=admin_export`。

## 5. 不可包含的資料

1. API token value。
2. Git remote URL 內嵌 username/password/token。
3. Webhook secret value。
4. Deploy key private key。
5. Repository secret value。
6. Cookie、session、personal access token。

## 6. 進入 GitHub migration 前的 gate

只有在 `gitea_repo_inventory_v1.status=ok` 後，才可以進入下一階段：

1. 每個 repo 建立 GitHub target 決策。
2. 每個 repo 產生 branch/tag SHA diff。
3. 每個 repo 盤點 workflow / webhook / runner / secret 名稱。
4. 每個 repo 建立 mirror / archive / keep-local 判定。
5. 產出 GitHub primary ADR 與 rollback plan。

S4.6 驗收通過只代表「脫敏清冊 payload 可以變成 evidence」；S4.9 owner response 驗收通過只代表「S4.7 coverage gap 有可審 scope decision」。任何 GitHub repo 建立、visibility 修改、refs sync、primary cutover 或 Gitea 停用仍需後續人工批准與 runtime gate。
