fix(github): expose operator unblock actions

This commit is contained in:
Your Name
2026-06-28 14:55:18 +08:00
parent e7c5013963
commit 96dfb53550
6 changed files with 184 additions and 24 deletions

View File

@@ -54,6 +54,7 @@ def build_delivery_closure_workbench(
github_summary = _dict(github.get("summary"))
github_boundaries = _dict(github.get("operation_boundaries"))
github_preflight = _dict(github.get("controlled_execution_preflight"))
github_operator_unblock = _dict(github_preflight.get("operator_unblock"))
gitea_status = _dict(gitea.get("program_status"))
gitea_rollups = _dict(gitea.get("rollups"))
runtime_status = _dict(runtime.get("program_status"))
@@ -123,7 +124,14 @@ def build_delivery_closure_workbench(
is True,
},
"href": "/governance?tab=automation-inventory",
"operator_unblock": github_operator_unblock,
"next_action": str(
_first_string(github_operator_unblock.get("required_actions"))
or github_operator_unblock.get("safe_handoff")
or github_preflight.get("operator_unblock_status")
or ""
)
or str(
_first_target_action(github_preflight.get("targets"))
or github.get("next_action")
or _first_target_action(github.get("targets"))
@@ -241,9 +249,7 @@ def build_delivery_closure_workbench(
"github_account_status": str(
github_preflight.get("github_account_status") or "unknown"
),
"github_account_suspended": github_preflight.get(
"github_account_suspended"
)
"github_account_suspended": github_preflight.get("github_account_suspended")
is True,
"github_api_forbidden_count": _int(
github_preflight.get("github_api_forbidden_count")
@@ -252,6 +258,11 @@ def build_delivery_closure_workbench(
github_preflight.get("controlled_apply_ready_count")
),
"github_blocked_preflight_target_count": github_preflight_blockers,
"github_operator_unblock_required": github_operator_unblock.get("required")
is True,
"github_operator_unblock_status": str(
github_operator_unblock.get("status") or ""
),
"secret_values_collected": False,
},
"source_statuses": source_statuses,

View File

@@ -35,6 +35,20 @@ _EXECUTION_AUTHORIZATION_SCHEMA_VERSION = (
_CONTROLLED_EXECUTION_PREFLIGHT_SCHEMA_VERSION = (
"github_target_controlled_execution_preflight_v1"
)
_GITHUB_WRITE_CHANNEL_RECHECK_COMMANDS = [
"gh api /user --jq '{login:.login}'",
"git push --dry-run origin HEAD:refs/heads/codex-github-write-channel-readonly-check",
]
_GITHUB_OPERATOR_UNBLOCK_ACTIONS = [
"complete_github_account_suspension_appeal_or_provide_authorized_writable_namespace",
"refresh_local_github_cli_login_without_sharing_tokens_or_cookies",
"rerun_github_write_channel_dry_run_before_create_or_refs_sync",
]
_GITHUB_OPERATOR_STILL_FORBIDDEN = [
"do_not_paste_pat_token_private_key_cookie_session_or_authorization_header",
"do_not_collect_private_clone_url_or_credential_value",
"do_not_force_push_delete_refs_or_change_public_visibility",
]
_PREFLIGHT_SCHEMA_VERSION = "github_target_owner_response_intake_preflight_v1"
_PREFLIGHT_MODE = "validate_owner_response_only_no_persist_no_github_write"
_SAFE_CREDENTIAL_REVIEW_SCHEMA_VERSION = (
@@ -2092,6 +2106,9 @@ def _controlled_execution_preflight_readiness(
create_channel_ready = summary.get("github_create_repo_channel_ready") is True
refs_channel_ready = summary.get("github_refs_sync_channel_ready") is True
write_channel_ready = create_channel_ready and refs_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"))
preflight_ready = (
bool(preflight_targets)
and authorization_summary["authorization_present"] is True
@@ -2110,6 +2127,12 @@ def _controlled_execution_preflight_readiness(
for row in preflight_targets
if row.get("github_repo")
}
operator_unblock = _github_write_channel_operator_unblock(
github_account_status=github_account_status,
github_account_suspended=github_account_suspended,
github_api_forbidden_count=github_api_forbidden_count,
github_write_channel_ready=write_channel_ready,
)
return {
"schema_version": str(
payload.get("schema_version")
@@ -2129,9 +2152,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_account_status": github_account_status,
"github_account_suspended": github_account_suspended,
"github_api_forbidden_count": 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(
@@ -2161,6 +2184,9 @@ def _controlled_execution_preflight_readiness(
"required_preflight_checks": _strings(payload.get("required_preflight_checks")),
"rollback_plan": _dict(payload.get("rollback_plan")),
"post_apply_verifiers": _strings(payload.get("post_apply_verifiers")),
"operator_unblock_required": operator_unblock["required"],
"operator_unblock_status": operator_unblock["status"],
"operator_unblock": operator_unblock,
"operation_boundaries": {
"read_only_api_allowed": boundaries.get("read_only_api_allowed") is True,
"github_api_write_allowed_by_authorization": boundaries.get(
@@ -2187,6 +2213,40 @@ def _controlled_execution_preflight_readiness(
}
def _github_write_channel_operator_unblock(
*,
github_account_status: str,
github_account_suspended: bool,
github_api_forbidden_count: int,
github_write_channel_ready: bool,
) -> dict[str, Any]:
required = not github_write_channel_ready
if github_account_suspended:
status = "github_account_suspended_external_action_required"
elif required:
status = "github_write_channel_reauthentication_or_namespace_required"
else:
status = "github_write_channel_ready_no_operator_action"
return {
"required": required,
"status": status,
"github_account_status": github_account_status,
"github_account_suspended": github_account_suspended,
"github_api_forbidden_count": github_api_forbidden_count,
"required_actions": _GITHUB_OPERATOR_UNBLOCK_ACTIONS if required else [],
"recheck_commands": _GITHUB_WRITE_CHANNEL_RECHECK_COMMANDS if required else [],
"still_forbidden": _GITHUB_OPERATOR_STILL_FORBIDDEN,
"safe_handoff": (
"GitHub owner must restore the suspended account or provide a writable "
"private GitHub namespace. Do not share tokens, cookies, private keys, "
"authorization headers, or private clone URLs."
)
if required
else "GitHub write channel is ready for controlled apply preflight.",
}
def _controlled_execution_target_summary(value: Any) -> dict[str, Any]:
row = _dict(value)
return {