feat(api): expose github account suspension preflight
This commit is contained in:
@@ -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")
|
||||
),
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user