1.0 公共 API 与 Conformance Matrix¶
本页定义 iamai 1.0 的公共兼容边界,并把所有规范条款映射到验证证据。1.0.0rc1 已完成候选
契约验证;1.0.0 正式发布后,表中的稳定承诺生效。后续修订必须同步更新规范、迁移指南、
golden manifest 和矩阵,不能把未说明的变化带入稳定版本。
API-VERSION-001:独立版本轴¶
调用方必须分别读取对应的公开常量,不能从包版本推导任一数据契约版本。
版本轴 |
公开标识 |
兼容边界 |
|---|---|---|
Python 公共 API |
|
顶层稳定 symbol、entry-point group、生命周期和弃用政策 |
配置 Schema |
|
JSON Schema 的字段、默认值、开放表、secret 标注和 |
序列化 wire format |
|
|
Python distribution |
package metadata( |
安装和发布版本;不替代以上任一 contract version |
API-SURFACE-001:稳定与 provisional symbol¶
tests/golden/public_api_v1.json 是 1.0 顶层 public symbol 的机器可读快照。iamai.__all__ 中
除下表 provisional 项之外的 symbol 是 1.0 稳定接口;on_command、on_message 和
on_event 别名也属于稳定接口。未进入 iamai.__all__ 的模块内部名称不构成兼容承诺。
状态 |
symbol |
承诺 |
|---|---|---|
Stable at 1.0.0 |
golden manifest 中除下一行外的全部 symbol |
遵守 弃用与兼容性政策,不得在 1.x 无警告删除或改变语义 |
Provisional |
|
可以从 |
provisional 不等于私有,也不代表生产就绪。依赖这些 symbol 的应用应固定 iamai minor 版本并运行 自己的集成测试。将 provisional 项提升为稳定项必须更新 manifest、文档和本矩阵。
矩阵格式¶
public-api-conformance.csv 是规范条款到证据的一一对应清单。每行 requirement_id 唯一;
automated 行给出可直接传给 Pytest 的完整 node id,manual 行给出发布检查及必须保存的证据。
verified 表示仓库已有自动证据;external-required 表示该发布门必须在最终树之外保存证据。
RC run URL 不能写回它验证的 git tree,否则新 commit 会改变被验证的 SHA 并形成自引用循环。
requirement_id |
scope |
source |
verification |
mode |
status |
|---|---|---|---|---|---|
SER-VERSION-001 |
serialization.version |
docs/reference/serialization-contract.rst#ser-version-001 |
tests/test_serialization_contract.py::test_serialization_contract_version_is_public |
automated |
verified |
SER-MESSAGE-001 |
serialization.message |
docs/reference/serialization-contract.rst#ser-message-001 |
tests/test_serialization_contract.py::test_message_valid_golden_round_trip_is_lossless_and_canonical |
automated |
verified |
SER-EVENT-001 |
serialization.event |
docs/reference/serialization-contract.rst#ser-event-001 |
tests/test_serialization_contract.py::test_event_valid_golden_round_trip_is_lossless_and_canonical |
automated |
verified |
SER-UNKNOWN-001 |
serialization.unknown-fields |
docs/reference/serialization-contract.rst#ser-unknown-001 |
tests/test_serialization_contract.py::test_same_major_readers_accept_additive_fields_and_emit_current_minor |
automated |
verified |
SER-CANONICAL-001 |
serialization.canonical |
docs/reference/serialization-contract.rst#ser-canonical-001 |
tests/test_serialization_contract.py::test_minimal_event_defaults_are_emitted_in_canonical_form |
automated |
verified |
SER-ERROR-001 |
serialization.error-limits |
docs/reference/serialization-contract.rst#ser-error-001 |
tests/test_serialization_contract.py::test_invalid_payload_goldens_have_stable_codes_and_paths; tests/test_serialization_contract.py::test_json_reader_rejects_non_object_malformed_duplicate_and_nonfinite_json; tests/test_serialization_contract.py::test_json_reader_rejects_fractional_numbers_outside_binary64_contract; tests/test_serialization_contract.py::test_json_reader_rejects_oversized_number_literals_before_conversion; tests/test_serialization_contract.py::test_integer_contract_accepts_4096_digit_boundary; tests/test_serialization_contract.py::test_mapping_reader_and_writer_reject_integers_over_4096_digits; tests/test_serialization_contract.py::test_python_payload_and_writer_reject_nonfinite_numbers; tests/test_serialization_contract.py::test_python_event_payload_rejects_non_json_raw_values; tests/test_serialization_contract.py::test_python_payload_reader_and_writer_reject_cycles; tests/test_serialization_contract.py::test_readers_reject_excessive_nesting_with_stable_error; tests/test_serialization_contract.py::test_event_writer_rejects_invalid_message_state_with_stable_error; tests/test_serialization_contract.py::test_event_required_strings_must_be_present_and_non_empty |
automated |
verified |
SER-EVOLUTION-001 |
serialization.evolution |
docs/reference/serialization-contract.rst#ser-evolution-001 |
tests/test_serialization_contract.py::test_same_major_readers_accept_additive_fields_and_emit_current_minor |
automated |
verified |
LIF-START-001 |
lifecycle.start |
docs/reference/public-api-lifecycle.rst#lif-start-001 |
tests/test_public_api_lifecycle_contract.py::test_successful_cold_start_orders_plugins_before_adapters_and_is_idempotent |
automated |
verified |
LIF-START-002 |
lifecycle.rollback |
docs/reference/public-api-lifecycle.rst#lif-start-002 |
tests/test_public_api_lifecycle_contract.py::test_bootstrap_failure_rolls_back_started_plugins_and_preserves_error |
automated |
verified |
LIF-ADAPTER-001 |
lifecycle.adapter-failure |
docs/reference/public-api-lifecycle.rst#lif-adapter-001 |
tests/test_public_api_lifecycle_contract.py::test_adapter_failure_preserves_error_and_triggers_full_cleanup |
automated |
verified |
LIF-SHUTDOWN-001 |
lifecycle.shutdown |
docs/reference/public-api-lifecycle.rst#lif-shutdown-001 |
tests/test_public_api_lifecycle_contract.py::test_shutdown_saves_and_stops_plugins_independently_in_reverse_order |
automated |
verified |
LIF-RELOAD-001 |
lifecycle.admission-generation |
docs/reference/public-api-lifecycle.rst#lif-reload-001 |
tests/test_public_api_lifecycle_contract.py::test_reload_drains_the_complete_active_handler_pipeline |
automated |
verified |
LIF-RELOAD-002 |
lifecycle.drain-cancel-drop |
docs/reference/public-api-lifecycle.rst#lif-reload-002 |
tests/test_public_api_lifecycle_contract.py::test_lifecycle_cancellation_records_dropped_work |
automated |
verified |
LIF-RELOAD-003 |
lifecycle.plugin-reload |
docs/reference/public-api-lifecycle.rst#lif-reload-003 |
tests/test_public_api_lifecycle_contract.py::test_plugin_reload_stages_new_registry_before_startup_and_commits_atomically |
automated |
verified |
LIF-RELOAD-004 |
lifecycle.config-reload |
docs/reference/public-api-lifecycle.rst#lif-reload-004 |
tests/test_public_api_lifecycle_contract.py::test_config_reload_stages_both_registries_before_plugin_startup |
automated |
verified |
LIF-ORDER-001 |
lifecycle.order |
docs/reference/public-api-lifecycle.rst#lif-order-001 |
tests/test_public_api_lifecycle_contract.py::test_plugin_dependency_and_middleware_order_is_stable |
automated |
verified |
CTX-SCOPE-001 |
context.scope |
docs/reference/public-api-lifecycle.rst#ctx-scope-001 |
tests/test_public_api_lifecycle_contract.py::test_context_scope_is_distinct_per_handler_and_shared_with_middleware |
automated |
verified |
CTX-ROUTE-001 |
context.routing |
docs/reference/public-api-lifecycle.rst#ctx-route-001 |
tests/test_public_api_lifecycle_contract.py::test_context_routes_operations_and_di_with_documented_precedence |
automated |
verified |
CTX-DI-001 |
context.di-precedence |
docs/reference/public-api-lifecycle.rst#ctx-di-001 |
tests/test_public_api_lifecycle_contract.py::test_context_routes_operations_and_di_with_documented_precedence |
automated |
verified |
CTX-DI-002 |
context.di-cache |
docs/reference/public-api-lifecycle.rst#ctx-di-002 |
tests/test_public_api_lifecycle_contract.py::test_di_cache_is_shared_across_runtime_callback_boundaries |
automated |
verified |
CTX-INVALID-001 |
context.invalidation |
docs/reference/public-api-lifecycle.rst#ctx-invalid-001 |
tests/test_public_api_lifecycle_contract.py::test_reload_invalidates_context_runtime_surfaces_and_discards_session_backlog |
automated |
verified |
CTX-LIFECYCLE-001 |
context.lifecycle-request |
docs/reference/public-api-lifecycle.rst#ctx-lifecycle-001 |
tests/test_runtime_safety.py::test_context_reload_waits_until_handler_finishes |
automated |
verified |
EXT-PACKAGE-001 |
extension.packaging |
docs/reference/extensions.rst#ext-package-001 |
tests/test_installed_extensions.py::test_installed_entry_points_support_explicit_and_opt_in_auto_discovery |
automated |
verified |
EXT-COMPATIBILITY-001 |
extension.compatibility |
docs/reference/extensions.rst#ext-compatibility-001 |
tests/test_installed_extensions.py::test_standard_resolver_rejects_incompatible_iamai_requirement |
automated |
verified |
EXT-DISCOVERY-001 |
extension.discovery |
docs/reference/extensions.rst#ext-discovery-001 |
tests/test_installed_extensions.py::test_installed_entry_points_support_explicit_and_opt_in_auto_discovery; tests/test_package_discovery.py::test_plugin_entry_point_name_can_be_loaded_explicitly; tests/test_package_discovery.py::test_dotted_plugin_entry_point_survives_hot_reload; tests/test_package_discovery.py::test_auto_discover_plugins_loads_entry_points_and_honors_dependencies; tests/test_package_discovery.py::test_adapter_entry_point_name_can_be_loaded_explicitly; tests/test_package_discovery.py::test_auto_discover_adapters_loads_entry_points; tests/test_package_discovery.py::test_duplicate_entry_points_report_every_distribution_in_sorted_order; tests/test_package_discovery.py::test_plugin_entry_point_cannot_shadow_builtin_name; tests/test_package_discovery.py::test_adapter_entry_point_cannot_shadow_builtin_name; tests/test_package_discovery.py::test_plugin_entry_point_rejects_non_plugin_object; tests/test_package_discovery.py::test_adapter_entry_point_rejects_non_adapter_object; tests/test_package_discovery.py::test_plugin_entry_point_name_must_match_plugin_name; tests/test_package_discovery.py::test_adapter_entry_point_name_must_match_adapter_name; tests/test_package_discovery.py::test_entry_point_load_failure_preserves_original_cause; tests/test_package_discovery.py::test_auto_discovery_order_is_deterministic_across_groups; tests/test_package_discovery.py::test_auto_discovery_appends_sorted_entries_without_reordering_explicit_references; tests/test_package_discovery.py::test_explicit_loading_ignores_unrequested_broken_entry_points; tests/test_package_discovery.py::test_auto_discovery_reports_first_error_in_entry_point_name_order |
automated |
verified |
EXT-ADAPTER-001 |
adapter.metadata |
docs/reference/extensions.rst#ext-adapter-001 |
tests/test_adapter_conformance.py::test_adapter_conformance_helpers_accept_minimum_adapter_contract; tests/test_adapter_conformance.py::test_adapter_config_rejects_invalid_effective_name |
automated |
verified |
EXT-ADAPTERCONFIG-001 |
adapter.config |
docs/reference/extensions.rst#ext-adapterconfig-001 |
tests/test_adapter_conformance.py::test_adapter_config_constructs_and_checks_normalized_subset |
automated |
verified |
EXT-EVENT-001 |
adapter.event |
docs/reference/extensions.rst#ext-event-001 |
tests/test_adapter_conformance.py::test_adapter_conformance_helpers_reject_incomplete_event; tests/test_adapter_conformance.py::test_adapter_event_rejects_empty_required_fields; tests/test_adapter_conformance.py::test_adapter_event_requires_message_instance; tests/test_adapter_conformance.py::test_adapter_event_accepts_empty_message_and_raw |
automated |
verified |
EXT-OUTBOUND-001 |
adapter.outbound |
docs/reference/extensions.rst#ext-outbound-001 |
tests/test_adapter_conformance.py::test_adapter_conformance_helpers_accept_minimum_adapter_contract |
automated |
verified |
EXT-ERROR-001 |
adapter.error |
docs/reference/extensions.rst#ext-error-001 |
tests/test_adapter_conformance.py::test_adapter_error_preserves_error_type_message_and_identity |
automated |
verified |
EXT-LIFECYCLE-001 |
adapter.lifecycle |
docs/reference/extensions.rst#ext-lifecycle-001 |
tests/test_adapter_conformance.py::test_adapter_lifecycle_observes_ready_close_and_clean; tests/test_adapter_conformance.py::test_adapter_lifecycle_matches_runtime_close_then_cancel_contract; tests/test_adapter_conformance.py::test_adapter_cancellation_must_propagate_and_still_cleans; tests/test_adapter_conformance.py::test_adapter_start_failure_preserves_error_and_checks_cleanup; tests/test_adapter_conformance.py::test_adapter_conformance_helpers_accept_minimum_adapter_contract |
automated |
verified |
EXT-PLUGIN-001 |
plugin.metadata |
docs/reference/extensions.rst#ext-plugin-001 |
tests/test_plugin_conformance.py::test_metadata_and_dependency_helpers_accept_public_contract |
automated |
verified |
EXT-PLUGINCONFIG-001 |
plugin.config |
docs/reference/extensions.rst#ext-pluginconfig-001 |
tests/test_plugin_conformance.py::test_config_helper_supports_pydantic_and_dataclass_models |
automated |
verified |
EXT-DEPENDENCY-001 |
plugin.dependencies |
docs/reference/extensions.rst#ext-dependency-001 |
tests/test_plugin_conformance.py::test_dependency_helper_rejects_conflicting_ordering |
automated |
verified |
EXT-HANDLER-001 |
plugin.handler |
docs/reference/extensions.rst#ext-handler-001 |
tests/test_plugin_conformance.py::test_handler_and_permission_helpers_cover_allow_and_deny |
automated |
verified |
EXT-PERMISSION-001 |
plugin.permission |
docs/reference/extensions.rst#ext-permission-001 |
tests/test_plugin_conformance.py::test_handler_and_permission_helpers_cover_allow_and_deny |
automated |
verified |
EXT-PLUGINLIFECYCLE-001 |
plugin.lifecycle |
docs/reference/extensions.rst#ext-pluginlifecycle-001 |
tests/test_plugin_conformance.py::test_lifecycle_helper_accepts_sync_and_async_cleanup_checks; tests/test_plugin_conformance.py::test_lifecycle_cancellation_runs_recovery_cleanup; tests/test_plugin_conformance.py::test_startup_failure_helper_accepts_self_cleanup |
automated |
verified |
CFG-SCHEMA-001 |
config.schema-version |
docs/reference/extensions.rst#cfg-schema-001 |
tests/test_config_schema.py::test_root_schema_matches_versioned_contract_golden; tests/test_config_schema.py::test_extension_schemas_are_sorted_stable_and_open_to_unknown_tables; tests/test_config_schema.py::test_pydantic_and_dataclass_config_models_are_supported; tests/test_config_schema.py::test_schema_generation_does_not_execute_default_factories; tests/test_config_schema.py::test_core_defaults_and_false_state_are_explicit; tests/test_config_schema.py::test_write_only_is_explicit_and_not_inferred_from_field_names; tests/test_config_schema.py::test_builtin_extension_secret_annotations_and_defaults_are_visible; tests/test_config_schema.py::test_runtime_schema_uses_metadata_only_and_never_leaks_configured_secrets; tests/test_adapter_config_contract.py::test_builtin_adapter_secret_fields_are_explicitly_write_only; tests/test_adapter_config_contract.py::test_builtin_adapter_factory_defaults_are_static_in_schema; tests/test_installed_extensions.py::test_installed_entry_points_support_explicit_and_opt_in_auto_discovery |
automated |
verified |
CFG-EQUIVALENCE-001 |
config.schema-equivalence |
docs/reference/extensions.rst#cfg-equivalence-001 |
tests/test_config_schema.py::test_root_schema_matches_versioned_contract_golden; tests/test_config_schema.py::test_build_config_schema_exactly_matches_runtime_schema_for_loaded_extensions; tests/test_config_schema.py::test_no_argument_cli_schema_exactly_matches_runtime_schema; tests/test_config_schema.py::test_cli_schema_applies_configured_python_paths; tests/test_config_schema.py::test_cli_plugin_selector_remains_backward_compatible; tests/test_config_schema.py::test_cli_plugin_selector_applies_configured_python_paths; tests/test_management_api.py::test_management_api_exposes_read_only_runtime_payloads |
automated |
verified |
API-VERSION-001 |
api.version-axes |
docs/reference/public-api-conformance.rst#api-version-001 |
tests/test_public_api_compatibility.py::test_public_api_contract_version_and_entry_point_groups_are_public |
automated |
verified |
API-SURFACE-001 |
api.surface |
docs/reference/public-api-conformance.rst#api-surface-001 |
tests/test_public_api_compatibility.py::test_v1_public_api_matches_golden_manifest |
automated |
verified |
DEP-WARNING-001 |
deprecation.warning |
docs/reference/deprecation-policy.rst#dep-warning-001 |
tests/test_public_api_compatibility.py::test_deprecation_warning_exposes_stable_metadata; tests/test_public_api_compatibility.py::test_deprecation_warning_rejects_unknown_kind; tests/test_public_api_compatibility.py::test_deprecation_warning_rejects_invalid_required_metadata; tests/test_public_api_compatibility.py::test_deprecation_warning_rejects_invalid_replacement |
automated |
verified |
DEP-WINDOW-001 |
deprecation.window |
docs/reference/deprecation-policy.rst#dep-window-001 |
tests/test_docs_content.py::test_v1_public_api_docs_cover_compatibility_policy_and_migration |
automated |
verified |
DEP-REMOVAL-001 |
deprecation.removal |
docs/reference/deprecation-policy.rst#dep-removal-001 |
tests/test_docs_content.py::test_v1_public_api_docs_cover_compatibility_policy_and_migration |
automated |
verified |
DEP-EXCEPTION-001 |
deprecation.exception |
docs/reference/deprecation-policy.rst#dep-exception-001 |
tests/test_docs_content.py::test_v1_public_api_docs_cover_compatibility_policy_and_migration |
automated |
verified |
MIG-COVERAGE-001 |
migration.coverage |
docs/guides/migration-0.3-to-1.0.rst#mig-coverage-001 |
tests/test_docs_content.py::test_v1_public_api_docs_cover_compatibility_policy_and_migration |
automated |
verified |
RC-VALIDATE-001 |
release.rc-rehearsal |
docs/reference/public-api-conformance.rst#rc-validate-001 |
release.yml workflow_dispatch on merged dev 1.0.0rc1 head: validate, wheels, sdist, artifact, attestation all succeed; record run URL and headSha externally at https://github.com/retrofor/iamai/issues/434 |
manual |
external-required |
RC-VALIDATE-001:非发布 RC rehearsal¶
1.0.0rc1 的精确 head 必须通过 release.yml 的非 tag workflow_dispatch:validate、sdist、
全部 Linux、musllinux、Windows 和 macOS wheel、artifact download 与 provenance attestation 必须
全部成功。该 run 不得发布 PyPI 包或创建 GitHub Release。发布负责人必须把 GitHub Actions run URL
记录到 #434、PR comment 或 release checklist,并同时记录 headSha;失败、URL 缺失或
headSha 不等于合并后的 dev SHA 时,不得标记 1.0 契约完成。