feat(api): expose github account suspension preflight

This commit is contained in:
Your Name
2026-06-28 09:54:26 +08:00
parent f8e2b39ab3
commit e7542632ae
7 changed files with 359 additions and 212 deletions

View File

@@ -114,6 +114,13 @@ def build_delivery_closure_workbench(
"github_write_channel_ready"
)
is True,
"github_account_status": str(
github_preflight.get("github_account_status") or "unknown"
),
"github_account_suspended": github_preflight.get(
"github_account_suspended"
)
is True,
},
"href": "/governance?tab=automation-inventory",
"next_action": str(
@@ -231,6 +238,16 @@ def build_delivery_closure_workbench(
"github_write_channel_ready"
)
is True,
"github_account_status": str(
github_preflight.get("github_account_status") or "unknown"
),
"github_account_suspended": github_preflight.get(
"github_account_suspended"
)
is True,
"github_api_forbidden_count": _int(
github_preflight.get("github_api_forbidden_count")
),
"github_controlled_apply_ready_count": _int(
github_preflight.get("controlled_apply_ready_count")
),

View File

@@ -781,6 +781,13 @@ def build_github_target_private_backup_evidence_gate(
"github_write_channel_ready": controlled_preflight[
"github_write_channel_ready"
],
"github_account_status": controlled_preflight["github_account_status"],
"github_account_suspended": controlled_preflight[
"github_account_suspended"
],
"github_api_forbidden_count": controlled_preflight[
"github_api_forbidden_count"
],
"github_create_repo_channel_ready": controlled_preflight[
"github_create_repo_channel_ready"
],
@@ -1232,6 +1239,18 @@ def _build_target(
"canonical_source_ready": controlled_execution_preflight.get(
"canonical_source_ready"
),
"canonical_source_ref": controlled_execution_preflight.get(
"canonical_source_ref"
),
"canonical_source_sha": controlled_execution_preflight.get(
"canonical_source_sha"
),
"source_probe_status": controlled_execution_preflight.get(
"source_probe_status"
),
"source_warnings": _strings(
controlled_execution_preflight.get("source_warnings")
),
"github_collision_preflight_ready": controlled_execution_preflight.get(
"github_collision_preflight_ready"
),
@@ -1725,6 +1744,11 @@ def _require_controlled_execution_preflight_consistency(
github_404_count = sum(
1 for row in targets if row.get("github_readback_status") == "api_404_not_found"
)
github_forbidden_count = sum(
1
for row in targets
if row.get("github_readback_status") == "api_403_account_suspended"
)
source_ready_count = sum(
1 for row in targets if row.get("source_preflight_ready") is True
)
@@ -1742,6 +1766,8 @@ def _require_controlled_execution_preflight_consistency(
!= github_404_count
):
raise ValueError(f"{label}: GitHub 404 count must match targets")
if _int(summary.get("github_api_forbidden_count")) != github_forbidden_count + 1:
raise ValueError(f"{label}: GitHub forbidden count must match checked repos")
if _int(summary.get("source_preflight_ready_count")) != source_ready_count:
raise ValueError(f"{label}: source preflight ready count must match targets")
if _int(summary.get("create_private_repo_apply_ready_count")) != create_ready_count:
@@ -2103,6 +2129,9 @@ def _controlled_execution_preflight_readiness(
and authorization_summary["repo_creation_authorized"] is True
and authorization_summary["refs_sync_authorized"] is True,
"github_write_channel_ready": write_channel_ready,
"github_account_status": str(summary.get("github_account_status") or "unknown"),
"github_account_suspended": summary.get("github_account_suspended") is True,
"github_api_forbidden_count": _int(summary.get("github_api_forbidden_count")),
"github_create_repo_channel_ready": create_channel_ready,
"github_refs_sync_channel_ready": refs_channel_ready,
"github_connector_repo_creation_tool_available": summary.get(
@@ -2166,6 +2195,10 @@ def _controlled_execution_target_summary(value: Any) -> dict[str, Any]:
"target_selector": str(row.get("target_selector") or ""),
"source_resolution_status": str(row.get("source_resolution_status") or ""),
"source_candidate_type": str(row.get("source_candidate_type") or ""),
"canonical_source_ref": str(row.get("canonical_source_ref") or ""),
"canonical_source_sha": str(row.get("canonical_source_sha") or ""),
"source_probe_status": str(row.get("source_probe_status") or ""),
"source_warnings": _strings(row.get("source_warnings")),
"source_preflight_ready": row.get("source_preflight_ready") is True,
"canonical_source_ready": row.get("canonical_source_ready") is True,
"github_collision_preflight_ready": row.get("github_collision_preflight_ready")

View File

@@ -25,6 +25,9 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
assert data["summary"]["refs_sync_authorized"] is True
assert data["summary"]["workflow_trigger_authorized"] is True
assert data["summary"]["github_write_channel_ready"] is False
assert data["summary"]["github_account_status"] == "suspended"
assert data["summary"]["github_account_suspended"] is True
assert data["summary"]["github_api_forbidden_count"] == 6
assert data["summary"]["github_controlled_apply_ready_count"] == 0
assert data["summary"]["github_blocked_preflight_target_count"] == 5
assert data["summary"]["secret_values_collected"] is False
@@ -48,13 +51,15 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
assert lanes["github"]["blocker_count"] == 5
assert (
lanes["github"]["status"]
== "blocked_github_write_channel_and_source_preflight_required"
== "blocked_github_account_suspended_and_write_channel_required"
)
assert lanes["github"]["metric"]["verified"] == 4
assert lanes["github"]["metric"]["total"] == 9
assert lanes["github"]["metric"]["controlled_apply_ready"] == 0
assert lanes["github"]["metric"]["blocked_preflight"] == 5
assert lanes["github"]["metric"]["write_channel_ready"] is False
assert lanes["github"]["metric"]["github_account_status"] == "suspended"
assert lanes["github"]["metric"]["github_account_suspended"] is True
assert all(0 <= lane["completion_percent"] <= 100 for lane in lanes.values())
assert all(lane["tone"] in {"ok", "warn", "danger"} for lane in lanes.values())

View File

@@ -70,7 +70,10 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
snapshot["summary"]["github_missing_target_controlled_apply_ready_count"] == 0
)
assert snapshot["summary"]["github_missing_target_blocked_preflight_count"] == 5
assert snapshot["summary"]["github_missing_target_github_404_count"] == 5
assert snapshot["summary"]["github_missing_target_github_404_count"] == 0
assert snapshot["summary"]["github_account_status"] == "suspended"
assert snapshot["summary"]["github_account_suspended"] is True
assert snapshot["summary"]["github_api_forbidden_count"] == 6
assert snapshot["summary"]["private_backup_verified_count"] == 4
assert snapshot["summary"]["private_visibility_verified_count"] == 4
assert snapshot["summary"]["safe_credential_required_count"] == 9
@@ -228,14 +231,18 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
== "github_target_controlled_execution_preflight_v1"
)
assert controlled_preflight["status"] == (
"blocked_github_write_channel_and_source_preflight_required"
"blocked_github_account_suspended_and_write_channel_required"
)
assert controlled_preflight["authorization_ready"] is True
assert controlled_preflight["preflight_ready"] is False
assert controlled_preflight["github_write_channel_ready"] is False
assert controlled_preflight["github_account_status"] == "suspended"
assert controlled_preflight["github_account_suspended"] is True
assert controlled_preflight["github_api_forbidden_count"] == 6
assert controlled_preflight["github_create_repo_channel_ready"] is False
assert controlled_preflight["github_refs_sync_channel_ready"] is False
assert controlled_preflight["github_connector_missing_target_404_count"] == 5
assert controlled_preflight["source_preflight_ready_count"] == 5
assert controlled_preflight["github_connector_missing_target_404_count"] == 0
assert controlled_preflight["blocked_preflight_target_count"] == 5
assert controlled_preflight["controlled_apply_ready_count"] == 0
assert (
@@ -315,10 +322,14 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
assert targets["owenhytsai/ewoooc"]["refs_sync_authorized"] is True
assert targets["owenhytsai/ewoooc"]["execution_ready"] is True
assert targets["owenhytsai/ewoooc"]["controlled_apply_ready"] is False
assert targets["owenhytsai/ewoooc"]["source_preflight_ready"] is False
assert targets["owenhytsai/ewoooc"]["canonical_source_ready"] is False
assert targets["owenhytsai/ewoooc"]["source_preflight_ready"] is True
assert targets["owenhytsai/ewoooc"]["canonical_source_ready"] is True
assert (
"github_create_repo_channel_unavailable"
targets["owenhytsai/ewoooc"]["canonical_source_sha"]
== "f3e412cd211f5e4601204b256aeb95eae073b441"
)
assert (
"github_account_suspended_403"
in targets["owenhytsai/ewoooc"]["controlled_apply_blockers"]
)
assert targets["owenhytsai/ewoooc"]["private_backup_verified"] is False
@@ -362,17 +373,20 @@ def test_load_github_target_controlled_execution_preflight_from_committed_snapsh
)
assert (
preflight["status"]
== "blocked_github_write_channel_and_source_preflight_required"
== "blocked_github_account_suspended_and_write_channel_required"
)
assert preflight["authorization_ready"] is True
assert preflight["preflight_ready"] is False
assert preflight["github_write_channel_ready"] is False
assert preflight["github_account_status"] == "suspended"
assert preflight["github_account_suspended"] is True
assert preflight["github_api_forbidden_count"] == 6
assert preflight["github_create_repo_channel_ready"] is False
assert preflight["github_refs_sync_channel_ready"] is False
assert preflight["source_preflight_ready_count"] == 0
assert preflight["source_preflight_ready_count"] == 5
assert preflight["controlled_apply_ready_count"] == 0
assert preflight["blocked_preflight_target_count"] == 5
assert preflight["github_connector_missing_target_404_count"] == 5
assert preflight["github_connector_missing_target_404_count"] == 0
assert preflight["operation_boundaries"]["controlled_apply_allowed"] is False
assert preflight["operation_boundaries"]["secret_value_collection_allowed"] is False
assert "private_clone_url_credential" in preflight["still_forbidden"]
@@ -381,9 +395,13 @@ def test_load_github_target_controlled_execution_preflight_from_committed_snapsh
target_by_repo["owenhytsai/bitan-pharmacy"]["controlled_apply_ready"] is False
)
assert (
"local_worktree_has_tracked_changes"
"github_account_suspended_403"
in target_by_repo["owenhytsai/bitan-pharmacy"]["blockers"]
)
assert (
target_by_repo["owenhytsai/bitan-pharmacy"]["canonical_source_sha"]
== "e122c8cbd9522999fd9844c2b63790fadcc89c20"
)
assert target_by_repo["owenhytsai/VibeWork"]["refs_sync_apply_ready"] is False

View File

@@ -37,7 +37,10 @@ def test_github_target_private_backup_evidence_gate_endpoint_returns_read_only_g
assert data["summary"]["github_refs_sync_channel_ready"] is False
assert data["summary"]["github_missing_target_controlled_apply_ready_count"] == 0
assert data["summary"]["github_missing_target_blocked_preflight_count"] == 5
assert data["summary"]["github_missing_target_github_404_count"] == 5
assert data["summary"]["github_missing_target_github_404_count"] == 0
assert data["summary"]["github_account_status"] == "suspended"
assert data["summary"]["github_account_suspended"] is True
assert data["summary"]["github_api_forbidden_count"] == 6
assert data["summary"]["private_backup_verified_count"] == 4
assert data["summary"]["private_visibility_verified_count"] == 4
assert data["summary"]["safe_credential_evidence_intake_ready"] is True
@@ -141,22 +144,26 @@ def test_github_target_controlled_execution_preflight_endpoint_returns_write_gap
data = response.json()
assert data["schema_version"] == "github_target_controlled_execution_preflight_v1"
assert (
data["status"] == "blocked_github_write_channel_and_source_preflight_required"
data["status"]
== "blocked_github_account_suspended_and_write_channel_required"
)
assert data["authorization_ready"] is True
assert data["preflight_ready"] is False
assert data["github_write_channel_ready"] is False
assert data["github_account_status"] == "suspended"
assert data["github_account_suspended"] is True
assert data["github_api_forbidden_count"] == 6
assert data["github_create_repo_channel_ready"] is False
assert data["github_refs_sync_channel_ready"] is False
assert data["source_preflight_ready_count"] == 0
assert data["source_preflight_ready_count"] == 5
assert data["controlled_apply_ready_count"] == 0
assert data["blocked_preflight_target_count"] == 5
assert data["github_connector_missing_target_404_count"] == 5
assert data["github_connector_missing_target_404_count"] == 0
assert data["operation_boundaries"]["controlled_apply_allowed"] is False
assert data["operation_boundaries"]["secret_value_collection_allowed"] is False
assert data["tool_channel_readback"]["gh_cli_write_ready"] is False
assert data["targets"][0]["controlled_apply_ready"] is False
assert "github_create_repo_channel_unavailable" in data["targets"][0]["blockers"]
assert "github_account_suspended_403" in data["targets"][0]["blockers"]
assert "192.168.0." not in response.text

View File

@@ -48226,3 +48226,34 @@ production browser smoke:
**下一個 P0**
- commit feature正常 push 到 Gitea若 main CD idle/successnormal push `HEAD:main`,部署後 production readback 目標:`github_write_channel_ready=false``github_missing_target_controlled_apply_ready_count=0``blocked_preflight_target_count=5`,並確認 Workbench GitHub lane 顯示 preflight blocker。
- 後續真正 controlled apply 需要補 GitHub create repo channel 或可用 refs sync channel並逐 target 產生 source-of-truth diff / no-force dry-run仍不讀 secret、不收 private clone URL、不 force push。
## 2026-06-28 — 09:50 GitHub account suspended readback 與 source selector preflight 本地完成
**時間與來源**
- 2026-06-28 09:30-09:50 Asia/Taipei。
- 來源GitHub connector `_get_repo``git ls-remote origin`、本地 / 內網 git remote readback、feature branch `codex/github-redacted-evidence-validator-20260627`
**完成內容**
- GitHub live readback 從早前 404 / private admin 狀態變成 account-level 403connector 對 `owenhytsai/awoooi` 與 missing target 均回 `Sorry. Your account was suspended``git remote show origin` / `git ls-remote origin` 也回 `Your account is suspended`
- `docs/security/github-target-controlled-execution-preflight.snapshot.json` 更新為 `status=blocked_github_account_suspended_and_write_channel_required`
- controlled preflight 新增並固定:`github_account_status=suspended``github_account_suspended=true``github_api_forbidden_count=6``github_connector_missing_target_404_count=0`
- 5 個 missing target 的 source selector 已補齊到 committed remote main不把未提交本地變更偷偷納入 GitHub backup
- `owenhytsai/ewoooc``gitea:wooo/ewoooc:main``f3e412cd211f5e4601204b256aeb95eae073b441`
- `owenhytsai/bitan-pharmacy``internal-origin:bitan-pharmacy:main``e122c8cbd9522999fd9844c2b63790fadcc89c20`;本地 64 個 tracked changes 與 untracked changes 另列 source warning。
- `owenhytsai/tsenyang-website``internal-origin:tsenyang-website:main``b369ed8cb6666e8ddaa2d31e1418a02794fdea9d`;本地 29 個 tracked changes 與 untracked outputs 另列 source warning。
- `owenhytsai/VibeWork``gitea:wooo/vibework:main``76a4ee15026af278a3660ad4b4547e9308b107be`;本地 `48275cc52be79107e887147d3fe10310a887afe9` divergence 另列 source warning。
- `owenhytsai/agent-bounty-protocol``gitea:wooo/agent-bounty-protocol:main``b7a733f44f4f645dd21a9b4a9075b89c4a324f64`;本地 `0601df8bd9c0aaedb9ce3a226a6f1aeca645ca0a` divergence 另列 source warning且不代表 runtime apply。
- API / Workbench 新增 account suspended 欄位GitHub lane 顯示 account 403而不是誤導成單純缺 owner approval。
**本地驗證結果**
- `python3 -m json.tool docs/security/github-target-controlled-execution-preflight.snapshot.json`:通過。
- `python3 -m py_compile apps/api/src/services/github_target_private_backup_evidence_gate.py apps/api/src/services/delivery_closure_workbench.py apps/api/src/api/v1/agents.py`:通過。
- `python3.11 -m ruff check apps/api/src/services/github_target_private_backup_evidence_gate.py apps/api/src/services/delivery_closure_workbench.py apps/api/src/api/v1/agents.py apps/api/tests/test_github_target_private_backup_evidence_gate.py apps/api/tests/test_github_target_private_backup_evidence_gate_api.py apps/api/tests/test_delivery_closure_workbench_api.py`:通過。
- `DATABASE_URL=sqlite:///test.db PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_github_target_private_backup_evidence_gate.py apps/api/tests/test_github_target_private_backup_evidence_gate_api.py apps/api/tests/test_delivery_closure_workbench_api.py -q``20 passed`
- `git diff --check`:通過。
- 本地 readback snippetgate `github_account_status=suspended``github_account_suspended=True``github_api_forbidden_count=6`preflight `source_preflight_ready_count=5``controlled_apply_ready_count=0``github_connector_missing_target_404_count=0`Delivery Workbench GitHub lane `status=blocked_github_account_suspended_and_write_channel_required``blocker_count=5`
**為什麼仍不能全部推上 GitHub**
- 不是 owner / read-only / manual gate受控授權已開source selector 也已補到 5/5。
- 目前唯一立即阻擋是 GitHub account-level suspension / 403導致 create repo、private visibility readback、refs sync 都沒有可用通道。
- 不讀 token、不收 private clone URL、不用 force push、不建立 public repo、不刪 refsGitHub 帳號恢復或出現不讀 secret 的 create/write channel 後,下一步就是依 5 個 canonical source SHA 建 private repo 並 normal push。

View File

@@ -1,202 +1,238 @@
{
"schema_version": "github_target_controlled_execution_preflight_v1",
"generated_at": "2026-06-28T08:44:54+08:00",
"status": "blocked_github_write_channel_and_source_preflight_required",
"mode": "controlled_apply_preflight_no_secret_no_repo_write",
"authorization_source": "chat_authorization_2026-06-28_full_hard_gate_open",
"summary": {
"owner_execution_authorization_received_count": 1,
"authorized_missing_target_count": 5,
"github_connector_get_repo_checked_count": 6,
"github_connector_existing_private_admin_count": 1,
"github_connector_missing_target_404_count": 5,
"local_gh_auth_ready": false,
"github_connector_repo_creation_tool_available": false,
"github_connector_refs_write_tool_available": true,
"github_create_repo_channel_ready": false,
"github_refs_sync_channel_ready": false,
"source_preflight_ready_count": 0,
"create_private_repo_apply_ready_count": 0,
"refs_sync_apply_ready_count": 0,
"blocked_preflight_target_count": 5,
"write_performed": false,
"repo_creation_performed": false,
"visibility_change_performed": false,
"refs_sync_performed": false,
"workflow_trigger_performed": false,
"secret_values_collected": false,
"private_clone_urls_collected": false
},
"tool_channel_readback": {
"gh_cli_auth_status": "invalid_token_in_keyring",
"gh_cli_write_ready": false,
"github_connector_read_repo_ready": true,
"github_connector_create_repo_ready": false,
"github_connector_refs_write_ready": true,
"github_connector_verified_private_admin_repo": "owenhytsai/awoooi",
"github_connector_missing_target_status": "api_404_not_found",
"credential_collection_attempted": false,
"secret_value_collection_allowed": false
},
"required_preflight_checks": [
"confirm_target_owner_scope_is_owenhytsai",
"verify_github_repo_collision_with_authenticated_readback",
"select_canonical_source_without_copying_secret_values",
"verify_source_worktree_clean_or_pick_remote_source",
"build_source_of_truth_ref_diff",
"run_no_force_refs_sync_dry_run",
"confirm_private_visibility_post_create",
"run_post_sync_refs_readback"
],
"rollback_plan": {
"repo_creation": "new_private_repo_can_be_left_empty_or_archived_after_no_ref_sync; repo_delete_is_not_authorized_here",
"refs_sync": "normal_push_only; rollback_requires new forward commit or branch restore, never force push or ref delete",
"visibility": "private_only; public_visibility_is_forbidden",
"workflow_trigger": "post_sync_verification_only_after_refs_readback"
},
"post_apply_verifiers": [
"github_get_repo_visibility_private",
"github_default_branch_readback",
"github_refs_compare_against_canonical_source",
"awoooi_github_private_backup_evidence_gate_readback",
"delivery_closure_workbench_readback"
],
"operation_boundaries": {
"read_only_api_allowed": true,
"github_api_write_allowed_by_authorization": true,
"github_create_repo_channel_ready": false,
"github_refs_sync_channel_ready": false,
"controlled_apply_allowed": false,
"repo_creation_allowed": false,
"visibility_change_allowed": false,
"refs_sync_allowed": false,
"workflow_trigger_allowed": false,
"force_push_allowed": false,
"delete_refs_allowed": false,
"public_visibility_allowed": false,
"github_primary_switch_allowed": false,
"secret_value_collection_allowed": false,
"private_clone_url_collection_allowed": false,
"raw_payload_storage_allowed": false
},
"targets": [
{
"github_repo": "owenhytsai/ewoooc",
"github_readback_status": "api_404_not_found",
"target_selector": "github_owner=owenhytsai repo=ewoooc source_candidate=wooo/ewoooc",
"source_resolution_status": "blocked_canonical_source_ambiguous",
"source_candidate_type": "gitea_repo_exists_with_momo_lineage_conflict",
"source_preflight_ready": false,
"canonical_source_ready": false,
"github_collision_preflight_ready": true,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"canonical_source_ambiguous",
"momo_lineage_conflict_requires_source_truth_diff",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "produce ewoooc versus momo source-of-truth diff, then rerun create/sync dry-run"
"schema_version": "github_target_controlled_execution_preflight_v1",
"generated_at": "2026-06-28T09:48:36+08:00",
"status": "blocked_github_account_suspended_and_write_channel_required",
"mode": "controlled_apply_preflight_no_secret_no_repo_write",
"authorization_source": "chat_authorization_2026-06-28_full_hard_gate_open",
"summary": {
"owner_execution_authorization_received_count": 1,
"authorized_missing_target_count": 5,
"github_connector_get_repo_checked_count": 6,
"github_connector_readback_status": "api_403_account_suspended",
"github_account_status": "suspended",
"github_account_suspended": true,
"github_api_forbidden_count": 6,
"github_connector_existing_private_admin_count": 0,
"github_connector_missing_target_404_count": 0,
"local_gh_auth_ready": false,
"github_connector_repo_creation_tool_available": false,
"github_connector_refs_write_tool_available": true,
"github_create_repo_channel_ready": false,
"github_refs_sync_channel_ready": false,
"source_preflight_ready_count": 5,
"create_private_repo_apply_ready_count": 0,
"refs_sync_apply_ready_count": 0,
"blocked_preflight_target_count": 5,
"write_performed": false,
"repo_creation_performed": false,
"visibility_change_performed": false,
"refs_sync_performed": false,
"workflow_trigger_performed": false,
"secret_values_collected": false,
"private_clone_urls_collected": false
},
{
"github_repo": "owenhytsai/bitan-pharmacy",
"github_readback_status": "api_404_not_found",
"target_selector": "github_owner=owenhytsai repo=bitan-pharmacy source_candidate=local_internal_remote_snapshot",
"source_resolution_status": "blocked_local_worktree_dirty",
"source_candidate_type": "internal_remote_snapshot_candidate",
"source_preflight_ready": false,
"canonical_source_ready": false,
"github_collision_preflight_ready": true,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"local_worktree_has_tracked_changes",
"canonical_remote_source_not_committed_as_gitea_repo",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "choose clean local or internal remote source, run source diff, then rerun no-force refs dry-run"
"tool_channel_readback": {
"gh_cli_auth_status": "invalid_token_in_keyring_account_suspended",
"gh_cli_write_ready": false,
"github_connector_read_repo_ready": false,
"github_connector_create_repo_ready": false,
"github_connector_refs_write_ready": false,
"github_connector_verified_private_admin_repo": null,
"github_connector_account_status": "suspended",
"github_connector_forbidden_status": "api_403_account_suspended",
"github_connector_missing_target_status": "api_403_account_suspended",
"credential_collection_attempted": false,
"secret_value_collection_allowed": false
},
{
"github_repo": "owenhytsai/tsenyang-website",
"github_readback_status": "api_404_not_found",
"target_selector": "github_owner=owenhytsai repo=tsenyang-website source_candidate=local_internal_remote_snapshot",
"source_resolution_status": "blocked_local_worktree_dirty",
"source_candidate_type": "internal_remote_snapshot_candidate",
"source_preflight_ready": false,
"canonical_source_ready": false,
"github_collision_preflight_ready": true,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"local_worktree_has_tracked_and_untracked_changes",
"canonical_remote_source_not_committed_as_gitea_repo",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "select clean canonical source for tsenyang-website, then rerun no-force refs dry-run"
"required_preflight_checks": [
"confirm_target_owner_scope_is_owenhytsai",
"verify_github_repo_collision_with_authenticated_readback",
"select_canonical_source_without_copying_secret_values",
"verify_source_worktree_clean_or_pick_remote_source",
"build_source_of_truth_ref_diff",
"run_no_force_refs_sync_dry_run",
"confirm_private_visibility_post_create",
"run_post_sync_refs_readback"
],
"rollback_plan": {
"repo_creation": "new_private_repo_can_be_left_empty_or_archived_after_no_ref_sync; repo_delete_is_not_authorized_here",
"refs_sync": "normal_push_only; rollback_requires new forward commit or branch restore, never force push or ref delete",
"visibility": "private_only; public_visibility_is_forbidden",
"workflow_trigger": "post_sync_verification_only_after_refs_readback"
},
{
"github_repo": "owenhytsai/VibeWork",
"github_readback_status": "api_404_not_found",
"target_selector": "github_owner=owenhytsai repo=VibeWork source_candidate=wooo/vibework",
"source_resolution_status": "blocked_product_boundary_and_local_divergence",
"source_candidate_type": "gitea_repo_exists_local_worktree_diverged",
"source_preflight_ready": false,
"canonical_source_ready": false,
"github_collision_preflight_ready": true,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"product_boundary_requires_source_selector",
"local_worktree_ahead_behind_with_changes",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "select Gitea vibework or local VibeWork as canonical source, then run refs diff dry-run"
"post_apply_verifiers": [
"github_get_repo_visibility_private",
"github_default_branch_readback",
"github_refs_compare_against_canonical_source",
"awoooi_github_private_backup_evidence_gate_readback",
"delivery_closure_workbench_readback"
],
"operation_boundaries": {
"read_only_api_allowed": true,
"github_api_write_allowed_by_authorization": true,
"github_create_repo_channel_ready": false,
"github_refs_sync_channel_ready": false,
"controlled_apply_allowed": false,
"repo_creation_allowed": false,
"visibility_change_allowed": false,
"refs_sync_allowed": false,
"workflow_trigger_allowed": false,
"force_push_allowed": false,
"delete_refs_allowed": false,
"public_visibility_allowed": false,
"github_primary_switch_allowed": false,
"secret_value_collection_allowed": false,
"private_clone_url_collection_allowed": false,
"raw_payload_storage_allowed": false
},
{
"github_repo": "owenhytsai/agent-bounty-protocol",
"github_readback_status": "api_404_not_found",
"target_selector": "github_owner=owenhytsai repo=agent-bounty-protocol source_candidate=wooo/agent-bounty-protocol",
"source_resolution_status": "blocked_high_risk_runtime_surface",
"source_candidate_type": "gitea_repo_exists_high_risk_runtime_surface",
"source_preflight_ready": false,
"canonical_source_ready": false,
"github_collision_preflight_ready": true,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"large_dirty_scan_not_completed",
"runtime_surface_source_selector_required",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "finish bounded dirty/source scan without secrets, then run canonical refs dry-run"
}
],
"still_forbidden": [
"secret_value",
"token_value",
"private_key",
"cookie_or_session",
"authorization_header",
"private_clone_url_credential",
"repo_archive",
"git_object_pack",
"force_push",
"delete_refs",
"tag_rewrite",
"repo_delete",
"github_primary_switch",
"public_visibility",
"raw_runtime_secret_volume",
"unrelated_history_merge"
]
"targets": [
{
"github_repo": "owenhytsai/ewoooc",
"github_readback_status": "api_403_account_suspended",
"target_selector": "github_owner=owenhytsai repo=ewoooc source_candidate=wooo/ewoooc",
"source_resolution_status": "ready_gitea_main_selected_stale_momo_worktrees_excluded",
"source_candidate_type": "gitea_repo_exists_with_momo_lineage_conflict",
"canonical_source_ref": "gitea:wooo/ewoooc:main",
"canonical_source_sha": "f3e412cd211f5e4601204b256aeb95eae073b441",
"source_probe_status": "remote_main_verified_https_and_ssh",
"source_warnings": [
"local_ewoooc_dev_has_uncommitted_changes_excluded",
"momo_worktrees_have_stale_or_dirty_refs_excluded"
],
"source_preflight_ready": true,
"canonical_source_ready": true,
"github_collision_preflight_ready": false,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"github_account_suspended_403",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "restore GitHub write channel, create private repo, then normal-push gitea wooo/ewoooc main"
},
{
"github_repo": "owenhytsai/bitan-pharmacy",
"github_readback_status": "api_403_account_suspended",
"target_selector": "github_owner=owenhytsai repo=bitan-pharmacy source_candidate=local_internal_remote_snapshot",
"source_resolution_status": "ready_internal_remote_main_selected_dirty_worktree_excluded",
"source_candidate_type": "internal_remote_snapshot_candidate",
"canonical_source_ref": "internal-origin:bitan-pharmacy:main",
"canonical_source_sha": "e122c8cbd9522999fd9844c2b63790fadcc89c20",
"source_probe_status": "remote_main_verified",
"source_warnings": [
"local_worktree_has_64_tracked_changes_excluded",
"local_worktree_has_untracked_changes_excluded"
],
"source_preflight_ready": true,
"canonical_source_ready": true,
"github_collision_preflight_ready": false,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"github_account_suspended_403",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "restore GitHub write channel, create private repo, then normal-push internal bitan-pharmacy main; freeze dirty worktree separately if those changes must be backed up"
},
{
"github_repo": "owenhytsai/tsenyang-website",
"github_readback_status": "api_403_account_suspended",
"target_selector": "github_owner=owenhytsai repo=tsenyang-website source_candidate=local_internal_remote_snapshot",
"source_resolution_status": "ready_internal_remote_main_selected_dirty_worktree_excluded",
"source_candidate_type": "internal_remote_snapshot_candidate",
"canonical_source_ref": "internal-origin:tsenyang-website:main",
"canonical_source_sha": "b369ed8cb6666e8ddaa2d31e1418a02794fdea9d",
"source_probe_status": "remote_main_verified",
"source_warnings": [
"local_worktree_has_29_tracked_changes_excluded",
"local_worktree_has_untracked_outputs_excluded"
],
"source_preflight_ready": true,
"canonical_source_ready": true,
"github_collision_preflight_ready": false,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"github_account_suspended_403",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "restore GitHub write channel, create private repo, then normal-push internal tsenyang-website main; freeze dirty worktree separately if those changes must be backed up"
},
{
"github_repo": "owenhytsai/VibeWork",
"github_readback_status": "api_403_account_suspended",
"target_selector": "github_owner=owenhytsai repo=VibeWork source_candidate=wooo/vibework",
"source_resolution_status": "ready_gitea_main_selected_local_divergence_excluded",
"source_candidate_type": "gitea_repo_exists_local_worktree_diverged",
"canonical_source_ref": "gitea:wooo/vibework:main",
"canonical_source_sha": "76a4ee15026af278a3660ad4b4547e9308b107be",
"source_probe_status": "remote_main_verified",
"source_warnings": [
"local_vibework_head_48275cc52be79107e887147d3fe10310a887afe9_excluded",
"local_tracked_dirty_count_0"
],
"source_preflight_ready": true,
"canonical_source_ready": true,
"github_collision_preflight_ready": false,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"github_account_suspended_403",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "restore GitHub write channel, create private repo, then normal-push gitea wooo/vibework main; handle local VibeWork divergence separately"
},
{
"github_repo": "owenhytsai/agent-bounty-protocol",
"github_readback_status": "api_403_account_suspended",
"target_selector": "github_owner=owenhytsai repo=agent-bounty-protocol source_candidate=wooo/agent-bounty-protocol",
"source_resolution_status": "ready_gitea_main_selected_no_runtime_apply",
"source_candidate_type": "gitea_repo_exists_high_risk_runtime_surface",
"canonical_source_ref": "gitea:wooo/agent-bounty-protocol:main",
"canonical_source_sha": "b7a733f44f4f645dd21a9b4a9075b89c4a324f64",
"source_probe_status": "remote_main_verified",
"source_warnings": [
"local_agent_bounty_head_0601df8bd9c0aaedb9ce3a226a6f1aeca645ca0a_excluded",
"runtime_surface_not_applied_by_backup_sync"
],
"source_preflight_ready": true,
"canonical_source_ready": true,
"github_collision_preflight_ready": false,
"create_private_repo_apply_ready": false,
"refs_sync_apply_ready": false,
"controlled_apply_ready": false,
"blockers": [
"github_account_suspended_403",
"github_create_repo_channel_unavailable",
"github_refs_sync_channel_unavailable"
],
"next_action": "restore GitHub write channel, create private repo, then normal-push gitea wooo/agent-bounty-protocol main without runtime apply"
}
],
"still_forbidden": [
"secret_value",
"token_value",
"private_key",
"cookie_or_session",
"authorization_header",
"private_clone_url_credential",
"repo_archive",
"git_object_pack",
"force_push",
"delete_refs",
"tag_rewrite",
"repo_delete",
"github_primary_switch",
"public_visibility",
"raw_runtime_secret_volume",
"unrelated_history_merge"
]
}