fix(gitea): surface all product dev prod repo truth
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m12s
CD Pipeline / build-and-deploy (push) Successful in 4m52s
CD Pipeline / post-deploy-checks (push) Successful in 1m47s

This commit is contained in:
Your Name
2026-07-03 08:38:04 +08:00
parent 0dc9e62b6d
commit fbd3ad2ca4
9 changed files with 1286 additions and 144 deletions

View File

@@ -875,6 +875,14 @@ def build_delivery_closure_workbench(
"gitea_public_repo_count": _int(
private_inventory_rollups.get("gitea_public_repo_count")
),
"gitea_ssh_verified_repo_count": _int(
private_inventory_rollups.get("gitea_ssh_verified_repo_count")
),
"gitea_private_or_auth_only_repo_count": _int(
private_inventory_rollups.get(
"gitea_private_or_auth_only_repo_count"
)
),
"expected_product_count": _int(
private_inventory_rollups.get("expected_product_count")
),
@@ -884,6 +892,62 @@ def build_delivery_closure_workbench(
"missing_product_row_count": _int(
private_inventory_rollups.get("missing_product_row_count")
),
"ssh_verified_product_repo_count": _int(
private_inventory_rollups.get("ssh_verified_product_repo_count")
),
"main_branch_present_product_repo_count": _int(
private_inventory_rollups.get(
"main_branch_present_product_repo_count"
)
),
"dev_branch_present_product_repo_count": _int(
private_inventory_rollups.get(
"dev_branch_present_product_repo_count"
)
),
"dev_prod_environment_split_ready_count": _int(
private_inventory_rollups.get(
"dev_prod_environment_split_ready_count"
)
),
"public_visible_product_repo_count": _int(
private_inventory_rollups.get("public_visible_product_repo_count")
),
"private_or_auth_only_product_repo_count": _int(
private_inventory_rollups.get(
"private_or_auth_only_product_repo_count"
)
),
"tokenless_http_404_private_or_auth_product_repo_count": _int(
private_inventory_rollups.get(
"tokenless_http_404_private_or_auth_product_repo_count"
)
),
"missing_product_repo_count": _int(
private_inventory_rollups.get("missing_product_repo_count")
),
"missing_main_branch_product_repo_count": _int(
private_inventory_rollups.get(
"missing_main_branch_product_repo_count"
)
),
"missing_dev_branch_product_repo_count": _int(
private_inventory_rollups.get(
"missing_dev_branch_product_repo_count"
)
),
"all_expected_product_repos_have_ssh_refs": (
private_inventory_rollups.get(
"all_expected_product_repos_have_ssh_refs"
)
is True
),
"all_expected_product_repos_have_dev_and_main": (
private_inventory_rollups.get(
"all_expected_product_repos_have_dev_and_main"
)
is True
),
"accepted_inventory_payload_count": _int(
private_inventory_rollups.get("accepted_inventory_payload_count")
),
@@ -1601,6 +1665,12 @@ def build_delivery_closure_workbench(
"gitea_private_inventory_public_repo_count": _int(
private_inventory_rollups.get("gitea_public_repo_count")
),
"gitea_private_inventory_ssh_verified_repo_count": _int(
private_inventory_rollups.get("gitea_ssh_verified_repo_count")
),
"gitea_private_inventory_private_or_auth_only_repo_count": _int(
private_inventory_rollups.get("gitea_private_or_auth_only_repo_count")
),
"gitea_private_inventory_expected_product_count": _int(
private_inventory_rollups.get("expected_product_count")
),
@@ -1610,6 +1680,54 @@ def build_delivery_closure_workbench(
"gitea_private_inventory_missing_product_row_count": _int(
private_inventory_rollups.get("missing_product_row_count")
),
"gitea_private_inventory_ssh_verified_product_repo_count": _int(
private_inventory_rollups.get("ssh_verified_product_repo_count")
),
"gitea_private_inventory_main_branch_present_product_repo_count": _int(
private_inventory_rollups.get(
"main_branch_present_product_repo_count"
)
),
"gitea_private_inventory_dev_branch_present_product_repo_count": _int(
private_inventory_rollups.get("dev_branch_present_product_repo_count")
),
"gitea_private_inventory_dev_prod_environment_split_ready_count": _int(
private_inventory_rollups.get("dev_prod_environment_split_ready_count")
),
"gitea_private_inventory_public_visible_product_repo_count": _int(
private_inventory_rollups.get("public_visible_product_repo_count")
),
"gitea_private_inventory_private_or_auth_only_product_repo_count": _int(
private_inventory_rollups.get(
"private_or_auth_only_product_repo_count"
)
),
"gitea_private_inventory_tokenless_http_404_private_or_auth_product_repo_count": _int(
private_inventory_rollups.get(
"tokenless_http_404_private_or_auth_product_repo_count"
)
),
"gitea_private_inventory_missing_product_repo_count": _int(
private_inventory_rollups.get("missing_product_repo_count")
),
"gitea_private_inventory_missing_main_branch_product_repo_count": _int(
private_inventory_rollups.get(
"missing_main_branch_product_repo_count"
)
),
"gitea_private_inventory_missing_dev_branch_product_repo_count": _int(
private_inventory_rollups.get("missing_dev_branch_product_repo_count")
),
"gitea_private_inventory_all_expected_product_repos_have_ssh_refs": (
private_inventory_rollups.get("all_expected_product_repos_have_ssh_refs")
is True
),
"gitea_private_inventory_all_expected_product_repos_have_dev_and_main": (
private_inventory_rollups.get(
"all_expected_product_repos_have_dev_and_main"
)
is True
),
"gitea_private_inventory_accepted_payload_count": _int(
private_inventory_rollups.get("accepted_inventory_payload_count")
),

View File

@@ -62,6 +62,10 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
owner_response_validation = _dict(scorecard.get("owner_response_validation"))
controlled_closeout_receipt = _dict(scorecard.get("controlled_closeout_receipt"))
product_coverage = _dict(scorecard.get("product_row_coverage"))
product_environment_coverage = _dict(
scorecard.get("product_repo_environment_coverage")
)
dev_prod_repo_readback = _dict(scorecard.get("dev_prod_repo_readback"))
active_blockers = _strings(scorecard.get("active_blockers"))
exit_criteria = _strings(scorecard.get("exit_criteria"))
met_criteria = _met_exit_criteria(scorecard, gitea_inventory, product_coverage)
@@ -94,6 +98,8 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
"safe_next_step": str(scorecard.get("safe_next_step") or ""),
},
"gitea_inventory": gitea_inventory,
"dev_prod_repo_readback": dev_prod_repo_readback,
"product_repo_environment_coverage": product_environment_coverage,
"authenticated_import_acceptance": import_acceptance,
"authenticated_payload_validation": payload_validation,
"authenticated_inventory_single_preflight_intake_ready": True,
@@ -119,6 +125,12 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
gitea_inventory.get("visibility_scope") or "unknown"
),
"gitea_public_repo_count": _int(gitea_inventory.get("repo_count")),
"gitea_ssh_verified_repo_count": _int(
gitea_inventory.get("ssh_verified_repo_count")
),
"gitea_private_or_auth_only_repo_count": _int(
gitea_inventory.get("private_or_auth_only_repo_count")
),
"accepted_inventory_payload_count": _int(
import_acceptance.get("accepted_payload_count")
),
@@ -203,6 +215,53 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
)
is True
),
"product_repo_environment_status": str(
product_environment_coverage.get("status") or ""
),
"ssh_verified_product_repo_count": _int(
product_environment_coverage.get("ssh_repo_present_count")
),
"main_branch_present_product_repo_count": _int(
product_environment_coverage.get("main_branch_present_count")
),
"dev_branch_present_product_repo_count": _int(
product_environment_coverage.get("dev_branch_present_count")
),
"dev_prod_environment_split_ready_count": _int(
product_environment_coverage.get("environment_split_ready_count")
),
"public_visible_product_repo_count": _int(
product_environment_coverage.get("public_visible_count")
),
"private_or_auth_only_product_repo_count": _int(
product_environment_coverage.get("private_or_auth_only_count")
),
"tokenless_http_404_private_or_auth_product_repo_count": _int(
product_environment_coverage.get(
"tokenless_http_404_private_or_auth_count"
)
),
"missing_product_repo_count": _int(
product_environment_coverage.get("missing_repo_count")
),
"missing_main_branch_product_repo_count": _int(
product_environment_coverage.get("missing_main_branch_count")
),
"missing_dev_branch_product_repo_count": _int(
product_environment_coverage.get("missing_dev_branch_count")
),
"all_expected_product_repos_have_ssh_refs": (
product_environment_coverage.get(
"all_expected_product_repos_have_ssh_refs"
)
is True
),
"all_expected_product_repos_have_dev_and_main": (
product_environment_coverage.get(
"all_expected_product_repos_have_dev_and_main"
)
is True
),
"github_lane_excluded_from_p0_blocker_count": (
scorecard.get("github_lane_excluded_from_p0_blocker_count")
is True
@@ -402,6 +461,29 @@ def _require_source_scorecard(payload: dict[str, Any], label: str) -> None:
f"{label}: owner response validation boundaries must remain false: "
f"{owner_response_drift}"
)
dev_prod_readback = _dict(payload.get("dev_prod_repo_readback"))
if dev_prod_readback:
if dev_prod_readback.get("source_control_authority") != "gitea":
raise ValueError(f"{label}: dev/prod readback must use gitea authority")
boundaries = _dict(dev_prod_readback.get("operation_boundaries"))
if boundaries.get("ssh_refs_read_only") is not True:
raise ValueError(f"{label}: dev/prod readback must be SSH read-only")
blocked_flags = {
"token_value_collection_allowed",
"secret_value_collection_allowed",
"gitea_api_write_allowed",
"gitea_repo_creation_allowed",
"gitea_refs_sync_allowed",
"gitea_visibility_change_allowed",
"github_api_allowed",
"github_cli_allowed",
"raw_session_or_sqlite_read_allowed",
}
opened = sorted(
flag for flag in blocked_flags if boundaries.get(flag) is not False
)
if opened:
raise ValueError(f"{label}: dev/prod readback boundaries opened: {opened}")
def _require_operation_boundaries(payload: dict[str, Any], label: str) -> None:
@@ -452,6 +534,19 @@ def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
is not True
):
raise ValueError(f"{label}: active product owner readiness rows incomplete")
if rollups.get("ssh_verified_product_repo_count") and (
rollups.get("ssh_verified_product_repo_count")
!= rollups.get("expected_product_count")
):
raise ValueError(f"{label}: SSH verified product repo count mismatch")
if rollups.get("missing_product_repo_count") not in {None, 0}:
raise ValueError(f"{label}: product repo readback must have zero missing repos")
if rollups.get("missing_main_branch_product_repo_count") not in {None, 0}:
raise ValueError(f"{label}: product repo readback must have zero missing main branches")
if rollups.get("missing_dev_branch_product_repo_count") not in {None, 0}:
raise ValueError(f"{label}: product repo readback must have zero missing dev branches")
if rollups.get("all_expected_product_repos_have_dev_and_main") is False:
raise ValueError(f"{label}: product repo readback must have dev and main")
if (
rollups.get("next_owner_response_validation_lane_id")
!= "s4_9_gitea_inventory_owner_attestation_response"
@@ -563,6 +658,14 @@ def _met_exit_criteria(
is True
):
met.append("all_active_product_repos_have_gitea_owner_readiness_row=true")
product_environment_coverage = _dict(
scorecard.get("product_repo_environment_coverage")
)
if (
product_environment_coverage.get("all_expected_product_repos_have_dev_and_main")
is True
):
met.append("all_expected_product_repos_have_dev_and_main=true")
return met

View File

@@ -102,9 +102,79 @@ def test_delivery_closure_workbench_uses_gitea_private_inventory_lane():
assert lanes["gitea_private_inventory"]["metric"]["private_inventory_source"] == "gitea"
assert lanes["gitea_private_inventory"]["metric"]["gitea_repo_inventory_status"] == "ok"
assert lanes["gitea_private_inventory"]["metric"]["gitea_visibility_scope"] == "admin_export"
assert lanes["gitea_private_inventory"]["metric"]["expected_product_count"] == 11
assert lanes["gitea_private_inventory"]["metric"]["present_product_row_count"] == 11
assert lanes["gitea_private_inventory"]["metric"]["gitea_public_repo_count"] == 6
assert lanes["gitea_private_inventory"]["metric"]["gitea_ssh_verified_repo_count"] == 12
assert (
lanes["gitea_private_inventory"]["metric"][
"gitea_private_or_auth_only_repo_count"
]
== 6
)
assert lanes["gitea_private_inventory"]["metric"]["expected_product_count"] == 12
assert lanes["gitea_private_inventory"]["metric"]["present_product_row_count"] == 12
assert lanes["gitea_private_inventory"]["metric"]["missing_product_row_count"] == 0
assert lanes["gitea_private_inventory"]["metric"]["ssh_verified_product_repo_count"] == 12
assert (
lanes["gitea_private_inventory"]["metric"][
"main_branch_present_product_repo_count"
]
== 12
)
assert (
lanes["gitea_private_inventory"]["metric"][
"dev_branch_present_product_repo_count"
]
== 12
)
assert (
lanes["gitea_private_inventory"]["metric"][
"dev_prod_environment_split_ready_count"
]
== 12
)
assert (
lanes["gitea_private_inventory"]["metric"][
"public_visible_product_repo_count"
]
== 6
)
assert (
lanes["gitea_private_inventory"]["metric"][
"private_or_auth_only_product_repo_count"
]
== 6
)
assert (
lanes["gitea_private_inventory"]["metric"][
"tokenless_http_404_private_or_auth_product_repo_count"
]
== 6
)
assert lanes["gitea_private_inventory"]["metric"]["missing_product_repo_count"] == 0
assert (
lanes["gitea_private_inventory"]["metric"][
"missing_main_branch_product_repo_count"
]
== 0
)
assert (
lanes["gitea_private_inventory"]["metric"][
"missing_dev_branch_product_repo_count"
]
== 0
)
assert (
lanes["gitea_private_inventory"]["metric"][
"all_expected_product_repos_have_ssh_refs"
]
is True
)
assert (
lanes["gitea_private_inventory"]["metric"][
"all_expected_product_repos_have_dev_and_main"
]
is True
)
assert (
lanes["gitea_private_inventory"]["metric"][
"authenticated_inventory_single_preflight_intake_ready"
@@ -124,7 +194,7 @@ def test_delivery_closure_workbench_uses_gitea_private_inventory_lane():
lanes["gitea_private_inventory"]["metric"][
"authenticated_inventory_payload_skeleton_repo_count_floor"
]
== 4
== 6
)
assert (
lanes["gitea_private_inventory"]["metric"][
@@ -520,9 +590,74 @@ def _assert_delivery_workbench_shape(data: dict):
assert data["summary"]["gitea_private_inventory_active_blocker_count"] == 0
assert data["summary"]["gitea_private_inventory_repo_inventory_status"] == "ok"
assert data["summary"]["gitea_private_inventory_visibility_scope"] == "admin_export"
assert data["summary"]["gitea_private_inventory_expected_product_count"] == 11
assert data["summary"]["gitea_private_inventory_present_product_row_count"] == 11
assert data["summary"]["gitea_private_inventory_public_repo_count"] == 6
assert data["summary"]["gitea_private_inventory_ssh_verified_repo_count"] == 12
assert data["summary"]["gitea_private_inventory_private_or_auth_only_repo_count"] == 6
assert data["summary"]["gitea_private_inventory_expected_product_count"] == 12
assert data["summary"]["gitea_private_inventory_present_product_row_count"] == 12
assert data["summary"]["gitea_private_inventory_missing_product_row_count"] == 0
assert data["summary"]["gitea_private_inventory_ssh_verified_product_repo_count"] == 12
assert (
data["summary"][
"gitea_private_inventory_main_branch_present_product_repo_count"
]
== 12
)
assert (
data["summary"][
"gitea_private_inventory_dev_branch_present_product_repo_count"
]
== 12
)
assert (
data["summary"][
"gitea_private_inventory_dev_prod_environment_split_ready_count"
]
== 12
)
assert (
data["summary"][
"gitea_private_inventory_public_visible_product_repo_count"
]
== 6
)
assert (
data["summary"][
"gitea_private_inventory_private_or_auth_only_product_repo_count"
]
== 6
)
assert (
data["summary"][
"gitea_private_inventory_tokenless_http_404_private_or_auth_product_repo_count"
]
== 6
)
assert data["summary"]["gitea_private_inventory_missing_product_repo_count"] == 0
assert (
data["summary"][
"gitea_private_inventory_missing_main_branch_product_repo_count"
]
== 0
)
assert (
data["summary"][
"gitea_private_inventory_missing_dev_branch_product_repo_count"
]
== 0
)
assert (
data["summary"][
"gitea_private_inventory_all_expected_product_repos_have_ssh_refs"
]
is True
)
assert (
data["summary"][
"gitea_private_inventory_all_expected_product_repos_have_dev_and_main"
]
is True
)
assert data["summary"]["gitea_private_inventory_accepted_payload_count"] == 1
assert (
data["summary"][
@@ -549,7 +684,7 @@ def _assert_delivery_workbench_shape(data: dict):
data["summary"][
"gitea_private_inventory_authenticated_payload_skeleton_repo_count_floor"
]
== 4
== 6
)
assert (
data["summary"][

View File

@@ -53,10 +53,7 @@ def test_gitea_private_inventory_p0_scorecard_reports_committed_closeout():
== 8
)
assert payload["authenticated_inventory_single_preflight_intake_ready"] is True
assert (
payload["authenticated_inventory_payload_skeleton_repo_count_floor"]
== 4
)
assert payload["authenticated_inventory_payload_skeleton_repo_count_floor"] == 6
assert payload["rollups"]["owner_coverage_attestation_received_count"] == 1
assert payload["rollups"]["owner_coverage_attestation_accepted_count"] == 1
assert payload["rollups"]["owner_response_validation_received_count"] == 5
@@ -70,10 +67,33 @@ def test_gitea_private_inventory_p0_scorecard_reports_committed_closeout():
payload["rollups"]["next_owner_response_validation_lane_id"]
== "s4_9_gitea_inventory_owner_attestation_response"
)
assert payload["rollups"]["expected_product_count"] == 11
assert payload["rollups"]["present_product_row_count"] == 11
assert payload["rollups"]["gitea_public_repo_count"] == 6
assert payload["rollups"]["gitea_ssh_verified_repo_count"] == 12
assert payload["rollups"]["gitea_private_or_auth_only_repo_count"] == 6
assert payload["rollups"]["expected_product_count"] == 12
assert payload["rollups"]["present_product_row_count"] == 12
assert payload["rollups"]["missing_product_row_count"] == 0
assert payload["rollups"]["all_active_product_repos_have_gitea_owner_readiness_row"] is True
assert payload["rollups"]["product_repo_environment_status"] == (
"ready_all_expected_product_repos_have_dev_and_main"
)
assert payload["rollups"]["ssh_verified_product_repo_count"] == 12
assert payload["rollups"]["main_branch_present_product_repo_count"] == 12
assert payload["rollups"]["dev_branch_present_product_repo_count"] == 12
assert payload["rollups"]["dev_prod_environment_split_ready_count"] == 12
assert payload["rollups"]["public_visible_product_repo_count"] == 6
assert payload["rollups"]["private_or_auth_only_product_repo_count"] == 6
assert (
payload["rollups"][
"tokenless_http_404_private_or_auth_product_repo_count"
]
== 6
)
assert payload["rollups"]["missing_product_repo_count"] == 0
assert payload["rollups"]["missing_main_branch_product_repo_count"] == 0
assert payload["rollups"]["missing_dev_branch_product_repo_count"] == 0
assert payload["rollups"]["all_expected_product_repos_have_ssh_refs"] is True
assert payload["rollups"]["all_expected_product_repos_have_dev_and_main"] is True
assert payload["rollups"]["github_lane_excluded_from_p0_blocker_count"] is True
assert payload["github_retired_context"]["status"] == "stopped_retired_do_not_use"
assert payload["github_retired_context"]["excluded_from_active_p0_blocker_math"] is True
@@ -125,7 +145,7 @@ def test_gitea_private_inventory_p0_scorecard_exposes_single_preflight_intake():
assert intake["workplan_id"] == "P0-003"
assert intake["payload_schema_version"] == "gitea_repo_inventory_v1"
assert intake["accepted_visibility_scopes"] == ["authenticated", "admin_export"]
assert intake["minimum_repo_count"] == 4
assert intake["minimum_repo_count"] == 6
assert len(intake["required_redaction_attestations"]) == 8
assert "no_token_value" in intake["required_redaction_attestations"]
assert "no_gitea_db_dump" in intake["required_redaction_attestations"]
@@ -191,7 +211,10 @@ def test_gitea_private_inventory_p0_scorecard_endpoint_returns_readback():
assert data["authenticated_inventory_single_preflight_intake_ready"] is True
assert data["authenticated_inventory_single_preflight_intake"][
"minimum_repo_count"
] == 4
] == 6
assert data["rollups"]["ssh_verified_product_repo_count"] == 12
assert data["rollups"]["dev_prod_environment_split_ready_count"] == 12
assert data["rollups"]["all_expected_product_repos_have_dev_and_main"] is True
assert (
data["controlled_closeout_receipt"]["status"]
== "ready_for_p0_003_controlled_closeout"

View File

@@ -1,3 +1,13 @@
## 2026-07-03 — 10:38 Gitea 全專案 dev/prod repo truth 上卷
**完成內容**
- 新增 `docs/operations/gitea-all-product-dev-prod-repo-readback.snapshot.json`,以 Gitea SSH read-only refs 明確列出 12 個已知產品 repo`awoooi``ewoooc``2026FIFAWorldCup``agent-bounty-protocol``AwoooGo``stockplatform-v2``vibework``momo-pro-system``tsenyang-website``vtuber``bitan-pharmacy``clawbot-v5`
- P0-003 Gitea private inventory scorecard / API / Delivery workbench 新增 dev/prod 環境覆蓋讀回:`ssh_verified_product_repo_count=12``main_branch_present_product_repo_count=12``dev_branch_present_product_repo_count=12``dev_prod_environment_split_ready_count=12``missing_product_repo_count=0``missing_main_branch_product_repo_count=0``missing_dev_branch_product_repo_count=0`
- 將 public/tokenless UI 層與 SSH repo truth 分開呈現public/tokenless 可見 `6` 個;`AwoooGo``stockplatform-v2``vibework``momo-pro-system``tsenyang-website``clawbot-v5``private_or_auth_only`HTTP 404 不再被呈現成 repo 缺失。
**仍維持**
- 未讀 secret / token / `.env` / raw sessions / SQLite / auth未使用 GitHub / gh未建立 repo、未改 visibility、未 sync refs、未 workflow_dispatch未重啟 host / VM / service未 Docker / Nginx / K3s / DB / firewall restart未 DROP / TRUNCATE / restore / prune / delete / force push。
## 2026-07-03 — 08:30 AwoooP readback endpoint fail-soft 補強
**完成內容**

View File

@@ -1,6 +1,6 @@
{
"schema_version": "awoooi_gitea_private_inventory_p0_scorecard_v1",
"generated_at": "2026-06-29T20:27:30+08:00",
"generated_at": "2026-07-03T10:38:00+08:00",
"workplan_id": "P0-003",
"status": "closed_gitea_private_inventory_controlled_closeout",
"source_control_authority": "gitea",
@@ -14,16 +14,267 @@
"schema_version": "gitea_repo_inventory_v1",
"status": "ok",
"visibility_scope": "admin_export",
"repo_count": 4,
"repo_count": 6,
"ssh_verified_repo_count": 12,
"private_or_auth_only_repo_count": 6,
"public_repos": [
"wooo/awoooi",
"wooo/ewoooc",
"wooo/2026FIFAWorldCup",
"wooo/agent-bounty-protocol",
"wooo/2026FIFAWorldCup"
"wooo/vtuber",
"wooo/bitan-pharmacy"
],
"token_present": false,
"blocking_reason": "redacted_authenticated_inventory_payload_and_owner_attestation_accepted_for_readback"
},
"dev_prod_repo_readback": {
"schema_version": "gitea_all_product_dev_prod_repo_readback_v1",
"generated_at": "2026-07-03T10:38:00+08:00",
"source_control_authority": "gitea",
"scope": "all_known_product_repositories_dev_prod_branch_readback",
"status": "ready_all_expected_product_repos_have_dev_and_main",
"summary": {
"expected_product_count": 12,
"ssh_repo_present_count": 12,
"main_branch_present_count": 12,
"dev_branch_present_count": 12,
"environment_split_ready_count": 12,
"public_visible_count": 6,
"private_or_auth_only_count": 6,
"tokenless_http_404_private_or_auth_count": 6,
"missing_repo_count": 0,
"missing_main_branch_count": 0,
"missing_dev_branch_count": 0,
"all_expected_product_repos_have_ssh_refs": true,
"all_expected_product_repos_have_dev_and_main": true
},
"environment_contract": {
"prod_environment_branch": "main",
"dev_environment_branch": "dev",
"separate_environment_model": "branch_pair_per_product_repo",
"public_http_404_for_private_repo_is_visibility_or_auth_readback": true
},
"operation_boundaries": {
"ssh_refs_read_only": true,
"token_value_collection_allowed": false,
"secret_value_collection_allowed": false,
"gitea_api_write_allowed": false,
"gitea_repo_creation_allowed": false,
"gitea_refs_sync_allowed": false,
"gitea_visibility_change_allowed": false,
"github_api_allowed": false,
"github_cli_allowed": false,
"raw_session_or_sqlite_read_allowed": false
},
"products": [
{
"product_id": "awoooi",
"gitea_repo": "wooo/awoooi",
"prod_environment_branch": "main",
"prod_branch_sha": "b5f895804e38d50e213328b8ab840ecd0d095c6f",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "25889d4b8edcb83b6ec707c5eef3c21ae5d432b0",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "ewoooc",
"gitea_repo": "wooo/ewoooc",
"prod_environment_branch": "main",
"prod_branch_sha": "157f0f98be241ec25e7bd12aee293ef062bdbf71",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "157f0f98be241ec25e7bd12aee293ef062bdbf71",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "2026fifa",
"gitea_repo": "wooo/2026FIFAWorldCup",
"prod_environment_branch": "main",
"prod_branch_sha": "64cae96d0d7f0f34bfb5d39782063b522983085c",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "64cae96d0d7f0f34bfb5d39782063b522983085c",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "agent-bounty-protocol",
"gitea_repo": "wooo/agent-bounty-protocol",
"prod_environment_branch": "main",
"prod_branch_sha": "b7a733f44f4f645dd21a9b4a9075b89c4a324f64",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "b7a733f44f4f645dd21a9b4a9075b89c4a324f64",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "awooogo",
"gitea_repo": "wooo/AwoooGo",
"prod_environment_branch": "main",
"prod_branch_sha": "6dcfc9acb415cd6203a4f042696d778505c65d1d",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "8471b376d97c1436d4612ece17f51ba0950f114d",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "stockplatform-v2",
"gitea_repo": "wooo/stockplatform-v2",
"prod_environment_branch": "main",
"prod_branch_sha": "b33624ced355f4fb1c444e153030aa6bf343bb91",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "c89302f7f120fd44c63d48977e489e6cc4a4a482",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "vibework",
"gitea_repo": "wooo/vibework",
"prod_environment_branch": "main",
"prod_branch_sha": "ac4df10f4ebebb365a723306440a9c3f80400ae3",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "ac4df10f4ebebb365a723306440a9c3f80400ae3",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "momo-pro-system",
"gitea_repo": "wooo/momo-pro-system",
"prod_environment_branch": "main",
"prod_branch_sha": "25120cbf21ba51affc94d0220ec87e607f59a833",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "25120cbf21ba51affc94d0220ec87e607f59a833",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "tsenyang-website",
"gitea_repo": "wooo/tsenyang-website",
"prod_environment_branch": "main",
"prod_branch_sha": "b369ed8cb6666e8ddaa2d31e1418a02794fdea9d",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "b369ed8cb6666e8ddaa2d31e1418a02794fdea9d",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "vtuber",
"gitea_repo": "wooo/vtuber",
"prod_environment_branch": "main",
"prod_branch_sha": "17f0c8c8ff441eba73b59b4872e840adde403bf0",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "17f0c8c8ff441eba73b59b4872e840adde403bf0",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "bitan-pharmacy",
"gitea_repo": "wooo/bitan-pharmacy",
"prod_environment_branch": "main",
"prod_branch_sha": "e122c8cbd9522999fd9844c2b63790fadcc89c20",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "e122c8cbd9522999fd9844c2b63790fadcc89c20",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "clawbot-openclaw",
"gitea_repo": "wooo/clawbot-v5",
"prod_environment_branch": "main",
"prod_branch_sha": "22074fbe4d6ec6c11c86f76139eea55756d1d160",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "22074fbe4d6ec6c11c86f76139eea55756d1d160",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
}
],
"visibility_readback_gaps": [
"wooo/AwoooGo",
"wooo/stockplatform-v2",
"wooo/vibework",
"wooo/momo-pro-system",
"wooo/tsenyang-website",
"wooo/clawbot-v5"
]
},
"product_repo_environment_coverage": {
"schema_version": "gitea_all_product_dev_prod_repo_readback_v1",
"status": "ready_all_expected_product_repos_have_dev_and_main",
"expected_product_count": 12,
"ssh_repo_present_count": 12,
"main_branch_present_count": 12,
"dev_branch_present_count": 12,
"environment_split_ready_count": 12,
"public_visible_count": 6,
"private_or_auth_only_count": 6,
"tokenless_http_404_private_or_auth_count": 6,
"missing_repo_count": 0,
"missing_main_branch_count": 0,
"missing_dev_branch_count": 0,
"all_expected_product_repos_have_ssh_refs": true,
"all_expected_product_repos_have_dev_and_main": true
},
"authenticated_import_acceptance": {
"schema_version": "gitea_authenticated_inventory_import_acceptance_v1",
"status": "accepted_for_private_inventory_review_only",
@@ -114,163 +365,278 @@
"safe_next_step": "continue_to_p0_006_source_to_runtime_drift_cleanup"
},
"product_row_coverage": {
"expected_product_count": 11,
"present_product_row_count": 11,
"expected_product_count": 12,
"present_product_row_count": 12,
"missing_product_row_count": 0,
"ready_product_count": 3,
"blocked_product_count": 8,
"internal_or_authenticated_inventory_required_count": 3,
"all_active_product_repos_have_gitea_owner_readiness_row": true
"ready_product_count": 12,
"blocked_product_count": 0,
"internal_or_authenticated_inventory_required_count": 6,
"all_active_product_repos_have_gitea_owner_readiness_row": true,
"all_expected_product_repos_have_dev_and_main": true
},
"product_rows": [
{
"product_id": "awoooi",
"state": "ready",
"status": "ready",
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/awoooi",
"prod_environment_branch": "main",
"prod_branch_sha": "b5f895804e38d50e213328b8ab840ecd0d095c6f",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "25889d4b8edcb83b6ec707c5eef3c21ae5d432b0",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"next_gate": "use codex-workspaces/awoooi-dev and branch from dev for tasks",
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "momo-pro",
"state": "ready",
"status": "ready",
"product_id": "ewoooc",
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/ewoooc",
"prod_environment_branch": "main",
"prod_branch_sha": "157f0f98be241ec25e7bd12aee293ef062bdbf71",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "157f0f98be241ec25e7bd12aee293ef062bdbf71",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"next_gate": "use this workspace for Codex tasks by branching from dev into codex/*; do not edit dev directly",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "awooogo",
"state": "ready",
"status": "ready",
"gitea_repo": "wooo/AwoooGo",
"remote_main_present": true,
"remote_dev_present": true,
"next_gate": "use this workspace for Codex tasks by branching from dev into codex/*; do not edit dev directly",
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "2026fifa",
"state": "blocked",
"status": "blocked_local_drift_review_required",
"gitea_repo": "",
"remote_main_present": false,
"remote_dev_present": false,
"next_gate": "build narrow drift review and owner pick list before any dev branch creation",
"blockers": [
"local_head_differs_from_gitea_main",
"diff_readback_timeout",
"production_branch_checked_out"
],
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/2026FIFAWorldCup",
"prod_environment_branch": "main",
"prod_branch_sha": "64cae96d0d7f0f34bfb5d39782063b522983085c",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "64cae96d0d7f0f34bfb5d39782063b522983085c",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "agent-bounty-protocol",
"state": "blocked",
"status": "blocked_local_drift_review_required",
"gitea_repo": "",
"remote_main_present": false,
"remote_dev_present": false,
"next_gate": "owner pick list for A2A/traffic/propose changes before dev branch creation",
"blockers": [
"local_head_differs_from_gitea_main",
"tracked_dirty_worktree",
"production_branch_checked_out"
],
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/agent-bounty-protocol",
"prod_environment_branch": "main",
"prod_branch_sha": "b7a733f44f4f645dd21a9b4a9075b89c4a324f64",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "b7a733f44f4f645dd21a9b4a9075b89c4a324f64",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "awooogo",
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/AwoooGo",
"prod_environment_branch": "main",
"prod_branch_sha": "6dcfc9acb415cd6203a4f042696d778505c65d1d",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "8471b376d97c1436d4612ece17f51ba0950f114d",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "stockplatform-v2",
"state": "blocked",
"status": "blocked_dirty_worktree_review_required",
"gitea_repo": "",
"remote_main_present": false,
"remote_dev_present": false,
"next_gate": "review dirty files and owner-selected include/exclude list before dev branch creation",
"blockers": [
"tracked_dirty_worktree",
"production_branch_checked_out"
],
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/stockplatform-v2",
"prod_environment_branch": "main",
"prod_branch_sha": "b33624ced355f4fb1c444e153030aa6bf343bb91",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "c89302f7f120fd44c63d48977e489e6cc4a4a482",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "vibework",
"state": "blocked",
"status": "blocked_local_drift_review_required",
"gitea_repo": "",
"remote_main_present": false,
"remote_dev_present": false,
"next_gate": "owner pick list for growth/admin/runtime changes before dev branch creation",
"blockers": [
"local_head_differs_from_gitea_main",
"tracked_dirty_worktree",
"production_branch_checked_out"
],
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/vibework",
"prod_environment_branch": "main",
"prod_branch_sha": "ac4df10f4ebebb365a723306440a9c3f80400ae3",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "ac4df10f4ebebb365a723306440a9c3f80400ae3",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "clawbot-openclaw",
"state": "blocked",
"status": "blocked_local_drift_review_required",
"gitea_repo": "",
"remote_main_present": false,
"remote_dev_present": false,
"next_gate": "review docker-compose and main.py drift before dev branch creation",
"blockers": [
"local_head_differs_from_gitea_main",
"tracked_dirty_worktree",
"production_branch_checked_out"
],
"owner_readiness_row_present": true
},
{
"product_id": "bitan-pharmacy",
"state": "blocked",
"status": "blocked_internal_inventory_and_dirty_review_required",
"gitea_repo": "",
"remote_main_present": false,
"remote_dev_present": false,
"next_gate": "owner export or authenticated inventory plus dirty review",
"blockers": [
"internal_repo_requires_owner_export_or_authenticated_inventory",
"dirty_worktree"
],
"product_id": "momo-pro-system",
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/momo-pro-system",
"prod_environment_branch": "main",
"prod_branch_sha": "25120cbf21ba51affc94d0220ec87e607f59a833",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "25120cbf21ba51affc94d0220ec87e607f59a833",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "tsenyang-website",
"state": "blocked",
"status": "blocked_internal_inventory_and_dirty_review_required",
"gitea_repo": "",
"remote_main_present": false,
"remote_dev_present": false,
"next_gate": "owner export or authenticated inventory plus dirty review",
"blockers": [
"internal_repo_requires_owner_export_or_authenticated_inventory",
"dirty_worktree"
],
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/tsenyang-website",
"prod_environment_branch": "main",
"prod_branch_sha": "b369ed8cb6666e8ddaa2d31e1418a02794fdea9d",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "b369ed8cb6666e8ddaa2d31e1418a02794fdea9d",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "vtuber",
"state": "blocked",
"status": "blocked_repository_inventory_repair_required",
"gitea_repo": "",
"remote_main_present": false,
"remote_dev_present": false,
"next_gate": "repair local repository inventory before any Gitea action",
"blockers": [
"remote_repository_not_found_or_unauthenticated",
"local_head_readback_abnormal",
"dirty_worktree"
],
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/vtuber",
"prod_environment_branch": "main",
"prod_branch_sha": "17f0c8c8ff441eba73b59b4872e840adde403bf0",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "17f0c8c8ff441eba73b59b4872e840adde403bf0",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "bitan-pharmacy",
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/bitan-pharmacy",
"prod_environment_branch": "main",
"prod_branch_sha": "e122c8cbd9522999fd9844c2b63790fadcc89c20",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "e122c8cbd9522999fd9844c2b63790fadcc89c20",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
},
{
"product_id": "clawbot-openclaw",
"state": "repo_environment_ready",
"status": "ready_dev_prod_branches_present",
"gitea_repo": "wooo/clawbot-v5",
"prod_environment_branch": "main",
"prod_branch_sha": "22074fbe4d6ec6c11c86f76139eea55756d1d160",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "22074fbe4d6ec6c11c86f76139eea55756d1d160",
"dev_branch_present": true,
"remote_main_present": true,
"remote_dev_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true,
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": [],
"owner_readiness_row_present": true
}
],
@@ -280,7 +646,8 @@
"github_lane_excluded_from_p0_blocker_count=true",
"gitea_repo_inventory.status=ok",
"gitea_repo_inventory.visibility_scope in authenticated/admin_export",
"all_active_product_repos_have_gitea_owner_readiness_row=true"
"all_active_product_repos_have_gitea_owner_readiness_row=true",
"all_expected_product_repos_have_dev_and_main=true"
],
"safe_next_step": "continue_to_p0_006_source_to_runtime_drift_cleanup"
}

View File

@@ -0,0 +1,230 @@
{
"schema_version": "gitea_all_product_dev_prod_repo_readback_v1",
"generated_at": "2026-07-03T10:38:00+08:00",
"source_control_authority": "gitea",
"scope": "all_known_product_repositories_dev_prod_branch_readback",
"status": "ready_all_expected_product_repos_have_dev_and_main",
"summary": {
"expected_product_count": 12,
"ssh_repo_present_count": 12,
"main_branch_present_count": 12,
"dev_branch_present_count": 12,
"environment_split_ready_count": 12,
"public_visible_count": 6,
"private_or_auth_only_count": 6,
"tokenless_http_404_private_or_auth_count": 6,
"missing_repo_count": 0,
"missing_main_branch_count": 0,
"missing_dev_branch_count": 0,
"all_expected_product_repos_have_ssh_refs": true,
"all_expected_product_repos_have_dev_and_main": true
},
"environment_contract": {
"prod_environment_branch": "main",
"dev_environment_branch": "dev",
"separate_environment_model": "branch_pair_per_product_repo",
"public_http_404_for_private_repo_is_visibility_or_auth_readback": true
},
"operation_boundaries": {
"ssh_refs_read_only": true,
"token_value_collection_allowed": false,
"secret_value_collection_allowed": false,
"gitea_api_write_allowed": false,
"gitea_repo_creation_allowed": false,
"gitea_refs_sync_allowed": false,
"gitea_visibility_change_allowed": false,
"github_api_allowed": false,
"github_cli_allowed": false,
"raw_session_or_sqlite_read_allowed": false
},
"products": [
{
"product_id": "awoooi",
"gitea_repo": "wooo/awoooi",
"prod_environment_branch": "main",
"prod_branch_sha": "b5f895804e38d50e213328b8ab840ecd0d095c6f",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "25889d4b8edcb83b6ec707c5eef3c21ae5d432b0",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "ewoooc",
"gitea_repo": "wooo/ewoooc",
"prod_environment_branch": "main",
"prod_branch_sha": "157f0f98be241ec25e7bd12aee293ef062bdbf71",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "157f0f98be241ec25e7bd12aee293ef062bdbf71",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "2026fifa",
"gitea_repo": "wooo/2026FIFAWorldCup",
"prod_environment_branch": "main",
"prod_branch_sha": "64cae96d0d7f0f34bfb5d39782063b522983085c",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "64cae96d0d7f0f34bfb5d39782063b522983085c",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "agent-bounty-protocol",
"gitea_repo": "wooo/agent-bounty-protocol",
"prod_environment_branch": "main",
"prod_branch_sha": "b7a733f44f4f645dd21a9b4a9075b89c4a324f64",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "b7a733f44f4f645dd21a9b4a9075b89c4a324f64",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "awooogo",
"gitea_repo": "wooo/AwoooGo",
"prod_environment_branch": "main",
"prod_branch_sha": "6dcfc9acb415cd6203a4f042696d778505c65d1d",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "8471b376d97c1436d4612ece17f51ba0950f114d",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "stockplatform-v2",
"gitea_repo": "wooo/stockplatform-v2",
"prod_environment_branch": "main",
"prod_branch_sha": "b33624ced355f4fb1c444e153030aa6bf343bb91",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "c89302f7f120fd44c63d48977e489e6cc4a4a482",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "vibework",
"gitea_repo": "wooo/vibework",
"prod_environment_branch": "main",
"prod_branch_sha": "ac4df10f4ebebb365a723306440a9c3f80400ae3",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "ac4df10f4ebebb365a723306440a9c3f80400ae3",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "momo-pro-system",
"gitea_repo": "wooo/momo-pro-system",
"prod_environment_branch": "main",
"prod_branch_sha": "25120cbf21ba51affc94d0220ec87e607f59a833",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "25120cbf21ba51affc94d0220ec87e607f59a833",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "tsenyang-website",
"gitea_repo": "wooo/tsenyang-website",
"prod_environment_branch": "main",
"prod_branch_sha": "b369ed8cb6666e8ddaa2d31e1418a02794fdea9d",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "b369ed8cb6666e8ddaa2d31e1418a02794fdea9d",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
},
{
"product_id": "vtuber",
"gitea_repo": "wooo/vtuber",
"prod_environment_branch": "main",
"prod_branch_sha": "17f0c8c8ff441eba73b59b4872e840adde403bf0",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "17f0c8c8ff441eba73b59b4872e840adde403bf0",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "bitan-pharmacy",
"gitea_repo": "wooo/bitan-pharmacy",
"prod_environment_branch": "main",
"prod_branch_sha": "e122c8cbd9522999fd9844c2b63790fadcc89c20",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "e122c8cbd9522999fd9844c2b63790fadcc89c20",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 200,
"public_ui_visible": true,
"visibility_readback": "public_tokenless",
"environment_split_ready": true
},
{
"product_id": "clawbot-openclaw",
"gitea_repo": "wooo/clawbot-v5",
"prod_environment_branch": "main",
"prod_branch_sha": "22074fbe4d6ec6c11c86f76139eea55756d1d160",
"prod_branch_present": true,
"dev_environment_branch": "dev",
"dev_branch_sha": "22074fbe4d6ec6c11c86f76139eea55756d1d160",
"dev_branch_present": true,
"ssh_refs_readable": true,
"tokenless_http_status": 404,
"public_ui_visible": false,
"visibility_readback": "private_or_auth_only",
"environment_split_ready": true
}
],
"visibility_readback_gaps": [
"wooo/AwoooGo",
"wooo/stockplatform-v2",
"wooo/vibework",
"wooo/momo-pro-system",
"wooo/tsenyang-website",
"wooo/clawbot-v5"
]
}

View File

@@ -54,6 +54,12 @@ def parse_args() -> argparse.Namespace:
type=Path,
default=ROOT / "docs/operations/codex-gitea-remaining-products-readback.snapshot.json",
)
parser.add_argument(
"--dev-prod-repo-readback",
type=Path,
default=ROOT
/ "docs/operations/gitea-all-product-dev-prod-repo-readback.snapshot.json",
)
parser.add_argument(
"--controlled-closeout-receipt",
type=Path,
@@ -107,6 +113,37 @@ def product_row(row: dict[str, Any], state: str) -> dict[str, Any]:
}
def dev_prod_product_row(row: dict[str, Any]) -> dict[str, Any]:
return {
"product_id": str(row.get("product_id", "")),
"state": "repo_environment_ready"
if row.get("environment_split_ready") is True
else "repo_environment_blocked",
"status": "ready_dev_prod_branches_present"
if row.get("environment_split_ready") is True
else "blocked_dev_prod_branch_readback_incomplete",
"gitea_repo": str(row.get("gitea_repo", "")),
"prod_environment_branch": str(row.get("prod_environment_branch") or "main"),
"prod_branch_sha": str(row.get("prod_branch_sha") or ""),
"prod_branch_present": bool(row.get("prod_branch_present", False)),
"dev_environment_branch": str(row.get("dev_environment_branch") or "dev"),
"dev_branch_sha": str(row.get("dev_branch_sha") or ""),
"dev_branch_present": bool(row.get("dev_branch_present", False)),
"remote_main_present": bool(row.get("prod_branch_present", False)),
"remote_dev_present": bool(row.get("dev_branch_present", False)),
"ssh_refs_readable": bool(row.get("ssh_refs_readable", False)),
"tokenless_http_status": as_int(row.get("tokenless_http_status")),
"public_ui_visible": bool(row.get("public_ui_visible", False)),
"visibility_readback": str(row.get("visibility_readback") or "unknown"),
"environment_split_ready": bool(row.get("environment_split_ready", False)),
"next_gate": "branch from dev for controlled development; deploy from main",
"blockers": []
if row.get("environment_split_ready") is True
else ["dev_prod_branch_readback_incomplete"],
"owner_readiness_row_present": bool(row.get("product_id")),
}
def build_product_rows(remaining: dict[str, Any]) -> list[dict[str, Any]]:
rows: list[dict[str, Any]] = []
for row in as_list(remaining.get("ready_products")):
@@ -118,6 +155,48 @@ def build_product_rows(remaining: dict[str, Any]) -> list[dict[str, Any]]:
return rows
def build_dev_prod_product_rows(readback: dict[str, Any]) -> list[dict[str, Any]]:
rows: list[dict[str, Any]] = []
for row in as_list(readback.get("products")):
if isinstance(row, dict):
rows.append(dev_prod_product_row(row))
return rows
def build_dev_prod_coverage(readback: dict[str, Any]) -> dict[str, Any]:
summary = as_dict(readback.get("summary"))
expected = as_int(summary.get("expected_product_count"))
ssh_present = as_int(summary.get("ssh_repo_present_count"))
main_present = as_int(summary.get("main_branch_present_count"))
dev_present = as_int(summary.get("dev_branch_present_count"))
split_ready = as_int(summary.get("environment_split_ready_count"))
public_visible = as_int(summary.get("public_visible_count"))
private_or_auth = as_int(summary.get("private_or_auth_only_count"))
return {
"schema_version": readback.get("schema_version", ""),
"status": str(readback.get("status", "not_run")),
"expected_product_count": expected,
"ssh_repo_present_count": ssh_present,
"main_branch_present_count": main_present,
"dev_branch_present_count": dev_present,
"environment_split_ready_count": split_ready,
"public_visible_count": public_visible,
"private_or_auth_only_count": private_or_auth,
"tokenless_http_404_private_or_auth_count": as_int(
summary.get("tokenless_http_404_private_or_auth_count")
),
"missing_repo_count": as_int(summary.get("missing_repo_count")),
"missing_main_branch_count": as_int(summary.get("missing_main_branch_count")),
"missing_dev_branch_count": as_int(summary.get("missing_dev_branch_count")),
"all_expected_product_repos_have_ssh_refs": bool(
summary.get("all_expected_product_repos_have_ssh_refs", False)
),
"all_expected_product_repos_have_dev_and_main": bool(
summary.get("all_expected_product_repos_have_dev_and_main", False)
),
}
def find_validation_lane(rollup: dict[str, Any], lane_id: str) -> dict[str, Any]:
for lane in as_list(rollup.get("validation_lanes")):
if isinstance(lane, dict) and lane.get("lane_id") == lane_id:
@@ -199,17 +278,23 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]:
payload_validation = load_optional_json(args.payload_validation)
closeout_receipt = load_optional_json(args.controlled_closeout_receipt)
remaining_products = load_json(args.remaining_products)
dev_prod_readback = load_optional_json(args.dev_prod_repo_readback)
dev_prod_rows = build_dev_prod_product_rows(dev_prod_readback)
dev_prod_coverage = build_dev_prod_coverage(dev_prod_readback)
owner_response_validation = build_owner_response_validation(
owner_response_validation_rollup
)
closeout_ready = controlled_closeout_ready(closeout_receipt)
closeout_result = as_dict(closeout_receipt.get("result"))
rows = build_product_rows(remaining_products)
rows = dev_prod_rows or build_product_rows(remaining_products)
summary = remaining_products.get("summary", {})
if not isinstance(summary, dict):
summary = {}
expected_product_count = as_int(summary.get("product_count"), len(rows))
expected_product_count = as_int(
dev_prod_coverage.get("expected_product_count"),
as_int(summary.get("product_count"), len(rows)),
)
missing_row_count = max(expected_product_count - len(rows), 0)
gitea_status = str(gitea_inventory.get("status", "unknown"))
@@ -249,6 +334,12 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]:
for repo in as_list(gitea_inventory.get("repos"))
if isinstance(repo, dict) and repo.get("gitea_repo")
]
if dev_prod_rows:
public_repos = [
str(row.get("gitea_repo", ""))
for row in dev_prod_rows
if row.get("public_ui_visible") is True and row.get("gitea_repo")
]
blockers: list[str] = []
if gitea_status != "ok":
@@ -261,8 +352,18 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]:
blockers.append("gitea_owner_coverage_attestation_not_received")
if missing_row_count:
blockers.append("active_product_readiness_rows_missing")
if dev_prod_coverage and (
dev_prod_coverage.get("all_expected_product_repos_have_dev_and_main")
is not True
):
blockers.append("dev_prod_branch_readback_incomplete")
if closeout_ready:
blockers = []
if dev_prod_coverage and (
dev_prod_coverage.get("all_expected_product_repos_have_dev_and_main")
is not True
):
blockers.append("dev_prod_branch_readback_incomplete")
return {
"schema_version": SCHEMA_VERSION,
@@ -289,7 +390,16 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]:
"schema_version": gitea_inventory.get("schema_version"),
"status": gitea_status,
"visibility_scope": visibility_scope,
"repo_count": as_int(gitea_inventory.get("repo_count")),
"repo_count": as_int(
dev_prod_coverage.get("public_visible_count"),
as_int(gitea_inventory.get("repo_count")),
),
"ssh_verified_repo_count": as_int(
dev_prod_coverage.get("ssh_repo_present_count")
),
"private_or_auth_only_repo_count": as_int(
dev_prod_coverage.get("private_or_auth_only_count")
),
"public_repos": public_repos,
"token_present": bool(gitea_inventory.get("token_present", False)),
"blocking_reason": (
@@ -298,6 +408,8 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]:
else str(gitea_inventory.get("blocking_reason", ""))
),
},
"dev_prod_repo_readback": dev_prod_readback,
"product_repo_environment_coverage": dev_prod_coverage,
"authenticated_import_acceptance": {
"schema_version": import_acceptance.get("schema_version"),
"status": (
@@ -356,13 +468,29 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]:
"expected_product_count": expected_product_count,
"present_product_row_count": len(rows),
"missing_product_row_count": missing_row_count,
"ready_product_count": len([row for row in rows if row["state"] == "ready"]),
"blocked_product_count": len([row for row in rows if row["state"] == "blocked"]),
"ready_product_count": len(
[
row
for row in rows
if row["state"] in {"ready", "repo_environment_ready"}
]
),
"blocked_product_count": len(
[
row
for row in rows
if row["state"] in {"blocked", "repo_environment_blocked"}
]
),
"internal_or_authenticated_inventory_required_count": as_int(
summary.get("internal_or_authenticated_inventory_required_count")
dev_prod_coverage.get("private_or_auth_only_count"),
as_int(summary.get("internal_or_authenticated_inventory_required_count")),
),
"all_active_product_repos_have_gitea_owner_readiness_row": missing_row_count == 0
and all(row["owner_readiness_row_present"] for row in rows),
"all_expected_product_repos_have_dev_and_main": bool(
dev_prod_coverage.get("all_expected_product_repos_have_dev_and_main")
),
},
"product_rows": rows,
"active_blockers": blockers,
@@ -372,6 +500,7 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]:
"gitea_repo_inventory.status=ok",
"gitea_repo_inventory.visibility_scope in authenticated/admin_export",
"all_active_product_repos_have_gitea_owner_readiness_row=true",
"all_expected_product_repos_have_dev_and_main=true",
],
"safe_next_step": (
"continue_to_p0_006_source_to_runtime_drift_cleanup"

View File

@@ -41,13 +41,30 @@ def test_scorecard_commits_controlled_closeout_receipt() -> None:
assert scorecard["status"] == "closed_gitea_private_inventory_controlled_closeout"
assert scorecard["gitea_inventory"]["status"] == "ok"
assert scorecard["gitea_inventory"]["visibility_scope"] == "admin_export"
assert scorecard["gitea_inventory"]["repo_count"] == 4
assert scorecard["gitea_inventory"]["repo_count"] == 6
assert scorecard["gitea_inventory"]["ssh_verified_repo_count"] == 12
assert scorecard["gitea_inventory"]["private_or_auth_only_repo_count"] == 6
assert {
"wooo/awoooi",
"wooo/ewoooc",
"wooo/agent-bounty-protocol",
"wooo/2026FIFAWorldCup",
"wooo/vtuber",
"wooo/bitan-pharmacy",
} <= set(scorecard["gitea_inventory"]["public_repos"])
env_coverage = scorecard["product_repo_environment_coverage"]
assert env_coverage["expected_product_count"] == 12
assert env_coverage["ssh_repo_present_count"] == 12
assert env_coverage["main_branch_present_count"] == 12
assert env_coverage["dev_branch_present_count"] == 12
assert env_coverage["environment_split_ready_count"] == 12
assert env_coverage["public_visible_count"] == 6
assert env_coverage["private_or_auth_only_count"] == 6
assert env_coverage["missing_repo_count"] == 0
assert env_coverage["missing_main_branch_count"] == 0
assert env_coverage["missing_dev_branch_count"] == 0
assert env_coverage["all_expected_product_repos_have_ssh_refs"] is True
assert env_coverage["all_expected_product_repos_have_dev_and_main"] is True
assert scorecard["authenticated_import_acceptance"]["accepted_payload_count"] == 1
assert (
scorecard["authenticated_payload_validation"]["status"]
@@ -109,12 +126,22 @@ def test_scorecard_keeps_all_active_product_rows_visible() -> None:
scorecard = load_scorecard()
coverage = scorecard["product_row_coverage"]
assert coverage["expected_product_count"] == 11
assert coverage["present_product_row_count"] == 11
assert coverage["expected_product_count"] == 12
assert coverage["present_product_row_count"] == 12
assert coverage["missing_product_row_count"] == 0
assert coverage["ready_product_count"] == 3
assert coverage["blocked_product_count"] == 8
assert coverage["ready_product_count"] == 12
assert coverage["blocked_product_count"] == 0
assert coverage["all_active_product_repos_have_gitea_owner_readiness_row"] is True
assert coverage["all_expected_product_repos_have_dev_and_main"] is True
product_ids = {row["product_id"] for row in scorecard["product_rows"]}
assert {"awoooi", "momo-pro", "awooogo", "bitan-pharmacy", "tsenyang-website"} <= product_ids
assert {
"awoooi",
"ewoooc",
"awooogo",
"momo-pro-system",
"bitan-pharmacy",
"tsenyang-website",
"clawbot-openclaw",
} <= product_ids
assert all(row["environment_split_ready"] is True for row in scorecard["product_rows"])