refactor: complete host module and event contracts

This commit is contained in:
jxxghp
2026-08-22 13:21:52 +08:00
parent e61b5168ad
commit 677f6a66c2
9 changed files with 3497 additions and 72 deletions
+4 -2
View File
@@ -13,8 +13,8 @@
"runtime_to_db": [],
"workflow_to_db": []
},
"edge_count": 6367,
"edge_sha256": "62c413857cd12dbaf4d31e4fad4c6b6c80f7dc747d0d5a74ecb61c44b4996822",
"edge_count": 6369,
"edge_sha256": "62638f6e334e7deb05902ca1e50cdcd03245a85c207dd2b4efaa03306cd28187",
"edges": [
"app -> app.runtime",
"app -> app.runtime.compat",
@@ -5436,7 +5436,9 @@
"app.runtime.event.binding -> app.runtime.log",
"app.runtime.event.contracts -> app.schemas",
"app.runtime.event.contracts -> app.schemas.event",
"app.runtime.event.contracts -> app.schemas.mediaserver",
"app.runtime.event.contracts -> app.schemas.types",
"app.runtime.event.contracts -> app.schemas.workflow",
"app.runtime.event.dispatch -> app.runtime",
"app.runtime.event.dispatch -> app.runtime.correlation",
"app.runtime.event.dispatch -> app.runtime.event",
File diff suppressed because it is too large Load Diff
+19 -3
View File
@@ -18,7 +18,7 @@ from app.schemas.types import ChainEventType, EventType, MediaType
def test_every_event_enum_has_complete_contract() -> None:
"""53 个广播/链式事件必须全部登记且 legacy 项必须解释原因"""
"""53 个广播/链式事件必须全部登记并绑定 typed payload"""
expected = {*EventType, *ChainEventType}
assert set(EVENT_CONTRACTS) == expected
@@ -26,8 +26,24 @@ def test_every_event_enum_has_complete_contract() -> None:
for contract in EVENT_CONTRACTS.values():
assert contract.mode in {"broadcast", "chain"}
assert contract.payload_contract
if contract.payload_contract == "legacy_dict":
assert contract.legacy_reason
assert contract.payload_model is not None
assert contract.payload_contract != "legacy_dict"
assert contract.legacy_reason is None
def test_extensible_plugin_payload_accepts_custom_fields_without_shape_change() -> None:
"""插件动作 contract 只校验公共字段,插件自定义字段和原始 dict 均保持不变。"""
payload = {
"plugin_id": "DemoPlugin",
"action": "refresh",
"plugin_owned_field": {"value": 1},
}
assert validate_event_payload(EventType.PluginAction, payload) == ()
event = Event(EventType.PluginAction, payload)
assert event.event_data is payload
assert event.event_data["plugin_owned_field"] == {"value": 1}
def test_typed_payload_is_validated_without_changing_public_shape() -> None:
+11 -7
View File
@@ -19,15 +19,19 @@ RUNTIME_BASELINE = (
)
def test_all_scanned_module_methods_resolve_a_contract() -> None:
"""架构快照中的所有字符串方法都必须能解析到稳定聚合规则"""
def test_all_scanned_host_module_methods_have_explicit_v2_contracts() -> None:
"""架构快照中的全部宿主字符串方法都必须显式登记 V2 契约"""
payload = json.loads(RUNTIME_BASELINE.read_text(encoding="utf-8"))
methods = payload["run_module"]["methods"]
methods = set(payload["run_module"]["methods"])
contracts = list_explicit_module_contracts()
assert methods
assert methods <= contracts.keys()
for method in methods:
contract = get_module_method_contract(method)
contract = contracts[method]
assert isinstance(contract.aggregation, ModuleResultAggregation)
assert contract.input_contract != "legacy_args"
assert contract.result_contract != "Any"
assert contract.plugin_short_circuit is True
@@ -59,11 +63,11 @@ def test_unknown_plugin_method_keeps_legacy_compatibility() -> None:
assert contract.supports_async is True
def test_contract_v2_freezes_at_least_twenty_high_value_methods() -> None:
"""首批能力必须具备可生成文档和诊断的完整 V2 字段。"""
def test_contract_v2_freezes_every_observed_host_method() -> None:
"""全部已观察宿主能力必须具备可生成文档和诊断的完整 V2 字段。"""
contracts = list_explicit_module_contracts()
assert len(contracts) >= 20
assert len(contracts) >= 211
for contract in contracts.values():
assert contract.version == 1
assert contract.input_contract != "legacy_args"