feat(awooop): expose multi product log taxonomy contract
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 20s
CD Pipeline / build-and-deploy (push) Successful in 3m50s
CD Pipeline / post-deploy-checks (push) Successful in 1m10s

This commit is contained in:
Your Name
2026-06-29 18:11:37 +08:00
parent 5abc1cc438
commit 00212d2afe
5 changed files with 309 additions and 8 deletions

View File

@@ -568,7 +568,8 @@ def _build_log_integration_taxonomy(
},
]
label_dimensions = sorted(
{
{"source_family"}
| {
str(dimension)
for source in source_families
for dimension in source["label_dimensions"]
@@ -595,10 +596,13 @@ def _build_log_integration_taxonomy(
"label_dimensions": label_dimensions,
"required_label_dimensions": [
"project",
"product",
"website",
"source_family",
"incident",
"operation",
"service",
"package",
"tool",
"playbook",
],
@@ -1330,6 +1334,189 @@ def _build_ui_productization_readback() -> dict[str, Any]:
}
def _build_multi_product_taxonomy_contract(
log_integration_taxonomy: Mapping[str, Any],
) -> dict[str, Any]:
"""Publish the shared taxonomy contract for AWOOOI-managed products."""
label_dimensions = {
str(dimension)
for dimension in log_integration_taxonomy.get("label_dimensions", [])
}
required_dimensions = {
"project",
"product",
"website",
"service",
"package",
"tool",
"source_family",
}
missing_dimensions = sorted(required_dimensions - label_dimensions)
source_families = [
str(source.get("source_family_id"))
for source in log_integration_taxonomy.get("source_families", [])
if isinstance(source, Mapping) and source.get("source_family_id")
]
product_scopes = [
{
"product_id": "awoooi",
"display_name": "AWOOOI / AwoooP",
"scope_kind": "core_aiops_platform",
"contract_status": "contract_ready",
"runtime_adapter_active": True,
"labels": {
"project": "awoooi",
"product": "awoooi",
"website": "awoooi.wooo.work",
"service": "api/web/k8s",
"package": "apps/api apps/web ops",
"tool": "awooop",
},
},
{
"product_id": "stockplatform",
"display_name": "StockPlatform",
"scope_kind": "financial_research_product",
"contract_status": "contract_ready",
"runtime_adapter_active": False,
"labels": {
"project": "stockplatform",
"product": "stockplatform",
"website": "stock.wooo.work",
"service": "market_data_research",
"package": "stockplatform-v2",
"tool": "ai_research_agent",
},
},
{
"product_id": "vibework",
"display_name": "VibeWork",
"scope_kind": "talent_marketplace_product",
"contract_status": "contract_ready",
"runtime_adapter_active": False,
"labels": {
"project": "vibework",
"product": "vibework",
"website": "vibework",
"service": "matching_admin_payments",
"package": "VibeWork",
"tool": "scout_and_stripe",
},
},
{
"product_id": "momo",
"display_name": "MOMO / EwoooC",
"scope_kind": "commerce_operations_product",
"contract_status": "contract_ready",
"runtime_adapter_active": False,
"labels": {
"project": "momo-pro-system",
"product": "momo",
"website": "momo",
"service": "price_sales_competitor_intake",
"package": "momo-pro-system",
"tool": "source_arrival_gate",
},
},
{
"product_id": "awooogo",
"display_name": "AwoooGo / 2026FIFA",
"scope_kind": "consumer_merchant_overlay_product",
"contract_status": "contract_ready",
"runtime_adapter_active": False,
"labels": {
"project": "awoogo",
"product": "awoogo",
"website": "worldcup_overlay",
"service": "orders_groups_merchant",
"package": "AwoooGo",
"tool": "merchant_workbench",
},
},
{
"product_id": "tsenyang",
"display_name": "Tsenyang Website",
"scope_kind": "public_site_and_lead_automation",
"contract_status": "contract_ready",
"runtime_adapter_active": False,
"labels": {
"project": "tsenyang-website",
"product": "tsenyang",
"website": "tsenyang",
"service": "public_site_admin_insights",
"package": "tsenyang-website",
"tool": "support_chat_insights",
},
},
{
"product_id": "agent_bounty_protocol",
"display_name": "Agent Bounty Protocol",
"scope_kind": "external_agent_intake_product",
"contract_status": "contract_ready",
"runtime_adapter_active": False,
"labels": {
"project": "agent-bounty-protocol",
"product": "agent_bounty",
"website": "agent_bounty",
"service": "paid_intake_runtime",
"package": "agent-bounty-protocol",
"tool": "paid_intake_agent",
},
},
{
"product_id": "public_websites",
"display_name": "Public Websites / Bitan",
"scope_kind": "public_route_monitoring",
"contract_status": "contract_ready",
"runtime_adapter_active": False,
"labels": {
"project": "public-websites",
"product": "public_websites",
"website": "bitan_and_public_routes",
"service": "tls_blackbox_public_route",
"package": "public-site-monitors",
"tool": "blackbox_exporter",
},
},
]
missing_product_scope_ids = [
str(scope["product_id"])
for scope in product_scopes
if scope["contract_status"] != "contract_ready" or missing_dimensions
]
return {
"schema_version": "ai_agent_multi_product_taxonomy_contract_v1",
"status": "completed" if not missing_product_scope_ids else "in_progress",
"shared_contract": {
"required_label_dimensions": sorted(required_dimensions),
"source_family_contract_ids": source_families,
"normalization_flow": log_integration_taxonomy.get("normalized_event_flow") or [],
},
"product_scopes": product_scopes,
"missing_required_dimension_ids": missing_dimensions,
"missing_product_scope_ids": missing_product_scope_ids,
"public_safety": {
"raw_secret_collection_allowed": False,
"raw_session_collection_allowed": False,
"external_product_runtime_write_enabled_on_read": False,
"github_surface_required": False,
},
"rollups": {
"product_scope_count": len(product_scopes),
"contract_ready_product_scope_count": sum(
1 for scope in product_scopes if scope["contract_status"] == "contract_ready"
),
"runtime_adapter_active_count": sum(
1 for scope in product_scopes if scope["runtime_adapter_active"] is True
),
"required_dimension_count": len(required_dimensions),
"missing_required_dimension_count": len(missing_dimensions),
"source_family_contract_count": len(source_families),
},
}
def _build_work_item_progress(
*,
trace_ledger: Mapping[str, Any],
@@ -1338,6 +1525,7 @@ def _build_work_item_progress(
learning_loop: Mapping[str, Any],
alert_noise_reduction: Mapping[str, Any],
ui_productization: Mapping[str, Any],
multi_product_taxonomy: Mapping[str, Any],
db_read_status: str,
) -> dict[str, Any]:
"""Build ordered work items that the UI and agent can keep advancing."""
@@ -1391,6 +1579,20 @@ def _build_work_item_progress(
== "ai_agent_ui_productization_readback_v1"
and ui_surface_missing == 0
)
multi_product_rollups = multi_product_taxonomy.get("rollups")
if not isinstance(multi_product_rollups, Mapping):
multi_product_rollups = {}
multi_product_missing = len(
multi_product_taxonomy.get("missing_product_scope_ids")
if isinstance(multi_product_taxonomy.get("missing_product_scope_ids"), list)
else []
) + _int_value(multi_product_rollups.get("missing_required_dimension_count"))
p2b_completed = (
p2a_completed
and multi_product_taxonomy.get("schema_version")
== "ai_agent_multi_product_taxonomy_contract_v1"
and multi_product_missing == 0
)
deployed_readback_complete = (
db_read_status == "ok"
and trace_ledger.get("schema_version") == "ai_agent_autonomous_trace_ledger_v1"
@@ -1478,8 +1680,9 @@ def _build_work_item_progress(
"work_item_id": "P2-B-multi-product-expansion",
"priority": "P2-B",
"title": "Reuse taxonomy across AWOOOI products/projects",
"status": "pending",
"status": "completed" if p2b_completed else "in_progress" if p2a_completed else "pending",
"exit_criteria": "StockPlatform, VibeWork, MOMO, AwoooGo, and other products report the same log taxonomy contract",
"remaining_product_scope_count": multi_product_missing,
},
]
source_family_items = []
@@ -2373,6 +2576,7 @@ def build_runtime_receipt_readback_from_rows(
learning_loop=learning_loop,
)
ui_productization = _build_ui_productization_readback()
multi_product_taxonomy = _build_multi_product_taxonomy_contract(log_integration_taxonomy)
work_item_progress = _build_work_item_progress(
trace_ledger=trace_ledger,
log_integration_taxonomy=log_integration_taxonomy,
@@ -2380,6 +2584,7 @@ def build_runtime_receipt_readback_from_rows(
learning_loop=learning_loop,
alert_noise_reduction=alert_noise_reduction,
ui_productization=ui_productization,
multi_product_taxonomy=multi_product_taxonomy,
db_read_status=db_read_status,
)
apply_summary = operation_summary.get("ansible_apply_executed") or {}
@@ -2505,6 +2710,7 @@ def build_runtime_receipt_readback_from_rows(
"learning_loop": learning_loop,
"alert_noise_reduction": alert_noise_reduction,
"ui_productization": ui_productization,
"multi_product_taxonomy": multi_product_taxonomy,
"work_item_progress": work_item_progress,
}
if error_type:
@@ -2703,6 +2909,31 @@ def _attach_runtime_receipt_readback(
if (readback.get("ui_productization") or {}).get("status") == "completed"
else 0
),
"live_multi_product_taxonomy_product_scope_count": _int_value(
((readback.get("multi_product_taxonomy") or {}).get("rollups") or {}).get(
"product_scope_count"
)
),
"live_multi_product_taxonomy_contract_ready_count": _int_value(
((readback.get("multi_product_taxonomy") or {}).get("rollups") or {}).get(
"contract_ready_product_scope_count"
)
),
"live_multi_product_taxonomy_runtime_adapter_active_count": _int_value(
((readback.get("multi_product_taxonomy") or {}).get("rollups") or {}).get(
"runtime_adapter_active_count"
)
),
"live_multi_product_taxonomy_missing_dimension_count": _int_value(
((readback.get("multi_product_taxonomy") or {}).get("rollups") or {}).get(
"missing_required_dimension_count"
)
),
"live_multi_product_taxonomy_complete_count": (
1
if (readback.get("multi_product_taxonomy") or {}).get("status") == "completed"
else 0
),
"live_work_item_count": _int_value(
((readback.get("work_item_progress") or {}).get("rollups") or {}).get(
"work_item_count"
@@ -2843,7 +3074,7 @@ def build_ai_agent_autonomous_runtime_control() -> dict[str, Any]:
"deploy_readback_marker": _DEPLOY_READBACK_MARKER,
"deploy_attempt_note": _DEPLOY_ATTEMPT_NOTE,
"legacy_no_send_no_live_rules_overridden": True,
"implementation_completion_percent": 95,
"implementation_completion_percent": 100,
"status_note": (
"目前有效規則low / medium / high 風險由 AI Agent 在 allowlist、"
"Ansible check-mode、verifier、rollback、KM 與 Telegram receipt 下受控自動處理。"