fix(gitea): include agent lifecycle workflow in runner contract

This commit is contained in:
ogt
2026-07-10 10:56:54 +08:00
parent 05414478fd
commit 81e00dc023
5 changed files with 78 additions and 21 deletions

View File

@@ -261,6 +261,9 @@ def build_gitea_workflow_source_inventory(repo_root: Path) -> dict[str, Any]:
"has_type_sync_check": "type-sync-check" in workflow_ids,
"has_onboarding_warning": "awoooi-onboarding-warning-step" in workflow_ids,
"has_agent_market_watch": "agent-market-watch" in workflow_ids,
"has_agent_version_lifecycle_watch": (
"agent-version-lifecycle-watch" in workflow_ids
),
"has_ai_technology_watch": "ai-technology-watch" in workflow_ids,
},
"professional_feature_rollups": {

View File

@@ -12,10 +12,12 @@ from src.services.gitea_actions_secret_variable_name_inventory import (
def test_gitea_actions_secret_variable_name_inventory_loader_is_value_safe() -> None:
payload = load_latest_gitea_actions_secret_variable_name_inventory()
assert payload["schema_version"] == "gitea_actions_secret_variable_name_inventory_v1"
assert (
payload["schema_version"] == "gitea_actions_secret_variable_name_inventory_v1"
)
assert payload["status"] == "gitea_actions_secret_variable_name_inventory_ready"
assert payload["ready"] is True
assert payload["summary"]["workflow_file_count"] == 12
assert payload["summary"]["workflow_file_count"] == 13
assert payload["summary"]["referenced_secret_name_count"] == 26
assert payload["summary"]["referenced_variable_name_count"] == 0
assert payload["summary"]["secret_values_collected"] is False
@@ -29,13 +31,18 @@ def test_gitea_actions_secret_variable_name_inventory_loader_is_value_safe() ->
assert "TELEGRAM_BOT_TOKEN" in names
assert "AWOOOI_GITEA_API_TOKEN" in names
assert "DATABASE_URL" in names
assert all(row["value_read_status"] == "not_read_by_design" for row in payload["secret_name_rows"])
assert all(
row["value_read_status"] == "not_read_by_design"
for row in payload["secret_name_rows"]
)
assert payload["metadata_verification_next_step"]["status"] == (
"redacted_configuration_metadata_required"
)
def test_gitea_actions_secret_variable_name_inventory_endpoint_returns_payload() -> None:
def test_gitea_actions_secret_variable_name_inventory_endpoint_returns_payload() -> (
None
):
app = FastAPI()
app.include_router(router, prefix="/api/v1")
client = TestClient(app)
@@ -45,5 +52,7 @@ def test_gitea_actions_secret_variable_name_inventory_endpoint_returns_payload()
assert response.status_code == 200
data = response.json()
assert data["schema_version"] == "gitea_actions_secret_variable_name_inventory_v1"
assert data["summary"]["referenced_secret_name_count"] == len(data["secret_name_rows"])
assert data["summary"]["referenced_secret_name_count"] == len(
data["secret_name_rows"]
)
assert data["summary"]["secret_values_collected"] is False

View File

@@ -148,13 +148,14 @@ def test_gitea_capability_readback_rolls_up_complete_feature_surface() -> None:
assert payload["rollups"]["expected_product_count"] == 12
assert payload["rollups"]["ssh_verified_product_repo_count"] == 12
assert payload["rollups"]["dev_prod_environment_split_ready_count"] == 12
assert payload["workflow_source_inventory"]["workflow_file_count"] == 12
assert payload["workflow_source_inventory"]["workflow_file_count"] == 13
professional_feature_rollups = payload["workflow_source_inventory"][
"professional_feature_rollups"
]
assert professional_feature_rollups["gitea_ignored_syntax_workflow_count"] == 9
assert professional_feature_rollups["gitea_ignored_syntax_workflow_count"] == 10
assert professional_feature_rollups["otel_workflow_count"] == 3
assert professional_feature_rollups["argocd_gitops_workflow_count"] == 1
assert professional_feature_rollups["notification_or_webhook_workflow_count"] == 9
assert (
professional_feature_rollups["registry_or_package_channel_workflow_count"] == 4
)
@@ -186,8 +187,8 @@ def test_gitea_capability_readback_rolls_up_complete_feature_surface() -> None:
assert capability_by_id["dev_prod_environment_split"]["status"] == "verified_ready"
assert capability_by_id["gitea_actions_workflows"]["status"] == "verified_ready"
assert capability_by_id["gitea_actions_workflows"]["metrics"] == {
"workflow_source_file_count": 12,
"workflow_contract_count": 12,
"workflow_source_file_count": 13,
"workflow_contract_count": 13,
}
assert capability_by_id["gitea_actions_runners"]["status"] == "verified_ready"
assert (

View File

@@ -20,9 +20,9 @@ def test_gitea_workflow_runner_health_endpoint_returns_committed_snapshot():
assert data["program_status"]["current_task_id"] == "P1-002"
assert data["program_status"]["next_task_id"] == "P1-003"
assert data["program_status"]["read_only_mode"] is True
assert data["rollups"]["total_workflows"] == len(data["workflow_records"]) == 12
assert data["rollups"]["workflows_with_schedule"] == 4
assert data["rollups"]["workflows_with_workflow_dispatch"] == 12
assert data["rollups"]["total_workflows"] == len(data["workflow_records"]) == 13
assert data["rollups"]["workflows_with_schedule"] == 5
assert data["rollups"]["workflows_with_workflow_dispatch"] == 13
assert data["rollups"]["workflow_ids_requiring_runner_attestation"] == []
assert data["rollups"]["runner_contracts_requiring_action"] == []
assert data["rollups"]["notification_contracts_quiet_success_count"] == 3
@@ -34,18 +34,34 @@ def test_gitea_workflow_runner_health_endpoint_returns_committed_snapshot():
assert data["approval_boundaries"]["workflow_modification_authorized"] is False
assert data["approval_boundaries"]["runner_mutation_authorized"] is False
assert data["approval_boundaries"]["migration_trigger_authorized"] is False
cd_pipeline = next(row for row in data["workflow_records"] if row["workflow_id"] == "cd_pipeline")
cd_pipeline = next(
row for row in data["workflow_records"] if row["workflow_id"] == "cd_pipeline"
)
assert cd_pipeline["runner_evidence_status"] == "non110_host_runner_mapped"
assert cd_pipeline["runner_labels"] == ["awoooi-non110-host"]
assert cd_pipeline["job_count"] == 5
e2e_health = next(row for row in data["workflow_records"] if row["workflow_id"] == "e2e_health")
e2e_health = next(
row for row in data["workflow_records"] if row["workflow_id"] == "e2e_health"
)
assert e2e_health["notification_policy"] == "failure_only"
ai_technology_watch = next(
row for row in data["workflow_records"] if row["workflow_id"] == "ai_technology_watch"
row
for row in data["workflow_records"]
if row["workflow_id"] == "ai_technology_watch"
)
assert ai_technology_watch["runner_labels"] == ["awoooi-non110-ubuntu"]
agent_version_lifecycle_watch = next(
row
for row in data["workflow_records"]
if row["workflow_id"] == "agent_version_lifecycle_watch"
)
assert agent_version_lifecycle_watch["runner_labels"] == ["awoooi-non110-ubuntu"]
assert agent_version_lifecycle_watch["notification_policy"] == "read_only_no_notify"
assert agent_version_lifecycle_watch["notify_bridge_calls"] == 0
harbor_repair = next(
row for row in data["workflow_records"] if row["workflow_id"] == "harbor_110_local_repair"
row
for row in data["workflow_records"]
if row["workflow_id"] == "harbor_110_local_repair"
)
assert harbor_repair["runner_evidence_status"] == "non110_host_runner_mapped"
assert "workflow 修改批准" in data["operator_contract"]["must_not_interpret_as"]

View File

@@ -11,6 +11,7 @@
"source_refs": [
"docs/schemas/gitea_workflow_runner_health_v1.schema.json",
".gitea/workflows/agent-market-watch.yaml",
".gitea/workflows/agent-version-lifecycle-watch.yaml",
".gitea/workflows/ai-technology-watch.yaml",
".gitea/workflows/ansible-lint.yml",
".gitea/workflows/awoooi-onboarding-warning-step.yaml",
@@ -22,6 +23,7 @@
".gitea/workflows/harbor-110-local-repair.yaml",
".gitea/workflows/run-migration.yml",
".gitea/workflows/type-sync-check.yaml",
"docs/evaluations/ai_agent_version_lifecycle_update_proposal_2026-07-10.json",
"scripts/ci/check-gitea-step-env-secrets.js",
"scripts/ci/cleanup-host-runner-workspace.sh",
"scripts/ci/wait-host-web-build-pressure.sh",
@@ -30,16 +32,16 @@
"scripts/ops/stop-stale-gitea-actions-jobs.sh"
],
"rollups": {
"total_workflows": 12,
"total_workflows": 13,
"by_workflow_status": {
"manifest_mapped": 12
"manifest_mapped": 13
},
"by_runner_evidence_status": {
"non110_runner_mapped": 9,
"non110_runner_mapped": 10,
"non110_host_runner_mapped": 3
},
"workflows_with_schedule": 4,
"workflows_with_workflow_dispatch": 12,
"workflows_with_schedule": 5,
"workflows_with_workflow_dispatch": 13,
"workflows_with_notify_bridge": 6,
"workflows_with_actionable_or_failure_quiet_policy": 3,
"workflow_ids_requiring_runner_attestation": [],
@@ -80,6 +82,32 @@
],
"next_action": "保留 actionable-only維持 non110 runner label不啟用額外通知或 paid API。"
},
{
"workflow_id": "agent_version_lifecycle_watch",
"file_ref": ".gitea/workflows/agent-version-lifecycle-watch.yaml",
"display_name": "Agent Version Lifecycle Watch",
"scope": "每週 AI Agent / SDK / framework 版本生命週期治理;只驗證 committed proposal queue不安裝 SDK、不呼叫 paid/model API、不改 workflow、不切 production provider route。",
"status": "manifest_mapped",
"risk_level": "medium",
"triggers": [
"workflow_dispatch",
"schedule"
],
"schedule_cadence": "每週二 09:00 Asia/Taipeicron=0 1 * * 2 UTC",
"runner_labels": [
"awoooi-non110-ubuntu"
],
"runner_evidence_status": "non110_runner_mapped",
"job_count": 1,
"notification_policy": "read_only_no_notify",
"notify_bridge_calls": 0,
"secrets_policy_status": "未讀取 Secretruntime_boundaries 明確禁止 package upgrade、workflow write、paid API、provider route switch 與 production write。",
"evidence_refs": [
".gitea/workflows/agent-version-lifecycle-watch.yaml",
"docs/evaluations/ai_agent_version_lifecycle_update_proposal_2026-07-10.json"
],
"next_action": "維持 no-write proposal validation若要升級成自動套版必須先補 replay/shadow/canary 與成本/路由批准。"
},
{
"workflow_id": "ai_technology_watch",
"file_ref": ".gitea/workflows/ai-technology-watch.yaml",