From 4426f2204d0bdb1615d563ada5a96f651c4abdce Mon Sep 17 00:00:00 2001 From: "agent.develop" Date: Fri, 18 Sep 2026 16:12:20 +0800 Subject: [PATCH] =?UTF-8?q?approve:=20[M4a]=20pbl=5Fagent=5Fruntime=20Agen?= =?UTF-8?q?t=20=E5=AE=9A=E4=B9=89=E4=B8=8E=E5=B7=A5=E5=85=B7=E6=B3=A8?= =?UTF-8?q?=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/test-run-2026-09-18.txt | 79 ++++++++++++++++++++++++++++++++++++ docs/work-log-2026-09-18.md | 21 ++++++++++ 2 files changed, 100 insertions(+) create mode 100644 docs/test-run-2026-09-18.txt diff --git a/docs/test-run-2026-09-18.txt b/docs/test-run-2026-09-18.txt new file mode 100644 index 0000000..7f9afed --- /dev/null +++ b/docs/test-run-2026-09-18.txt @@ -0,0 +1,79 @@ +# 测试执行记录 — pbl_domain_ext(M8) 2026-09-18T07:48:06Z + +命令: python3 -m unittest discover -s tests -p test_*.py -v +Python: Python 3.10.12 + +``` +test_bind_base_missing_raises_not_found (test_domain_ref.TestBindRef) ... ok +test_bind_duplicate_raises (test_domain_ref.TestBindRef) ... ok +test_bind_ext_invalid_json_string (test_domain_ref.TestBindRef) ... ok +test_bind_invalid_ref_id (test_domain_ref.TestBindRef) ... ok +test_bind_invalid_ref_type (test_domain_ref.TestBindRef) ... ok +test_bind_missing_tenant (test_domain_ref.TestBindRef) ... ok +test_bind_same_ref_other_tenant_ok (test_domain_ref.TestBindRef) +同一基表记录可被不同租户各自绑定(UNIQUE 含 tenant_id)。 ... ok +test_bind_world_ok (test_domain_ref.TestBindRef) ... ok +test_rebind_after_unbind_revives (test_domain_ref.TestBindRef) ... ok +test_access_denied_after_unbind (test_domain_ref.TestCheckRefAccess) ... ok +test_access_denied_cross_tenant (test_domain_ref.TestCheckRefAccess) ... ok +test_access_denied_dangling_base (test_domain_ref.TestCheckRefAccess) ... ok +test_access_denied_invalid_input_no_raise (test_domain_ref.TestCheckRefAccess) ... ok +test_access_denied_unbound (test_domain_ref.TestCheckRefAccess) ... ok +test_access_denied_wrong_class_or_team (test_domain_ref.TestCheckRefAccess) ... ok +test_access_granted (test_domain_ref.TestCheckRefAccess) ... ok +test_list_all_tenant_scoped (test_domain_ref.TestListRefs) ... ok +test_list_dangling_flag (test_domain_ref.TestListRefs) ... ok +test_list_filter_by_type_and_class (test_domain_ref.TestListRefs) ... ok +test_list_invalid_ref_type_filter (test_domain_ref.TestListRefs) ... ok +test_list_page_size_capped (test_domain_ref.TestListRefs) ... ok +test_list_pagination (test_domain_ref.TestListRefs) ... ok +test_bind_team_to_world_base_missing (test_domain_ref.TestTeamClassDimension) ... ok +test_bind_team_to_world_creates_ref (test_domain_ref.TestTeamClassDimension) ... ok +test_bind_team_to_world_duplicate_same_team (test_domain_ref.TestTeamClassDimension) ... ok +test_bind_team_to_world_requires_team_id (test_domain_ref.TestTeamClassDimension) ... ok +test_bind_team_to_world_updates_existing (test_domain_ref.TestTeamClassDimension) ... ok +test_get_team_worlds (test_domain_ref.TestTeamClassDimension) ... ok +test_get_team_worlds_requires_team_id (test_domain_ref.TestTeamClassDimension) ... ok +test_list_teams_by_class_groups (test_domain_ref.TestTeamClassDimension) ... ok +test_list_teams_by_class_members_from_governance (test_domain_ref.TestTeamClassDimension) ... ok +test_list_teams_by_class_requires_class_id (test_domain_ref.TestTeamClassDimension) ... ok +test_list_teams_by_class_tenant_scoped (test_domain_ref.TestTeamClassDimension) ... ok +test_list_teams_without_governance_table_degrades (test_domain_ref.TestTeamClassDimension) +治理模块未部署(无 pbl_team_member 表)时降级为空成员列表,不报错。 ... ok +test_get_world_context_base_missing_not_found (test_domain_ref.TestTenantIsolationQueries) ... ok +test_get_world_context_cross_tenant_forbidden (test_domain_ref.TestTenantIsolationQueries) ... ok +test_get_world_with_pbl_context_ok (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_entities_by_scene_ok (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_entities_cross_tenant_forbidden (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_scenes_by_world_ok (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_scenes_cross_tenant_forbidden (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_scenes_only_bound_visible (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_worlds_by_class_filter (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_worlds_by_tenant_empty_when_no_binding (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_worlds_by_tenant_only_bound (test_domain_ref.TestTenantIsolationQueries) ... ok +test_list_worlds_filters_dangling (test_domain_ref.TestTenantIsolationQueries) ... ok +test_base_layer_readonly_projection (test_domain_ref.TestThinExtensionInvariants) ... ok +test_base_tables_untouched (test_domain_ref.TestThinExtensionInvariants) ... ok +test_contract_13_interfaces_all_callable (test_domain_ref.TestThinExtensionInvariants) ... ok +test_contract_map_covers_dspy_files (test_domain_ref.TestThinExtensionInvariants) ... ok +test_load_module_registers_env_functions (test_domain_ref.TestThinExtensionInvariants) ... ok +test_load_path_registers_all_dspy (test_domain_ref.TestThinExtensionInvariants) ... ok +test_model_json_four_sections (test_domain_ref.TestThinExtensionInvariants) ... /d/pipeline/workspaces/0/sdlc_general/modules/pbl_domain_ext/tests/test_domain_ref.py:454: ResourceWarning: unclosed file <_io.TextIOWrapper name='/d/pipeline/workspaces/0/sdlc_general/modules/pbl_domain_ext/models/pbl_domain_ref.json' mode='r' encoding='utf-8'> + model = json.load(open(path, encoding='utf-8')) +ResourceWarning: Enable tracemalloc to get the object allocation traceback +ok +test_own_tables_single_and_matches_models (test_domain_ref.TestThinExtensionInvariants) ... ok +test_package_exports_match_init (test_domain_ref.TestThinExtensionInvariants) ... ok +test_get_ref_cross_tenant_not_found (test_domain_ref.TestUnbindGetUpdate) ... ok +test_get_ref_ok (test_domain_ref.TestUnbindGetUpdate) ... ok +test_unbind_missing (test_domain_ref.TestUnbindGetUpdate) ... ok +test_unbind_soft_delete (test_domain_ref.TestUnbindGetUpdate) ... ok +test_update_ref_missing (test_domain_ref.TestUnbindGetUpdate) ... ok +test_update_ref_ok (test_domain_ref.TestUnbindGetUpdate) ... ok +test_update_ref_rejects_key_fields (test_domain_ref.TestUnbindGetUpdate) ... ok + +---------------------------------------------------------------------- +Ran 62 tests in 0.064s + +OK +``` diff --git a/docs/work-log-2026-09-18.md b/docs/work-log-2026-09-18.md index 635a585..15b1dd1 100644 --- a/docs/work-log-2026-09-18.md +++ b/docs/work-log-2026-09-18.md @@ -80,3 +80,24 @@ - 分支:`main`(`modules/pbl_domain_ext`) - 本轮改动已落盘工作区;**git 收口由引擎在 PM 审核通过后统一执行**,本日志不自称已 commit/push(以引擎回填的「git 收口核验」段为准)。 + +## 6. 测试执行证据(QC 历史 #3:仅 py_compile 无执行记录 → 本轮补实测) + +- 执行命令:`python3 -m unittest discover -s tests -p 'test_*.py' -v`(环境无 pytest,site-packages 只读无法安装;unittest 为标准库等价执行器,用例本身即 unittest.TestCase,非降级替代) +- 实测结果:**Ran 62 tests — OK(0 failed / 0 error)**,完整逐条输出落盘 `docs/test-run-2026-09-18.txt` +- 覆盖维度(对应 QC 要求的「租户 / 权限 / 正常 / 异常」四类用例): + | 用例类 | 覆盖点 | + |---|---| + | `TestBindRef` | bind_ref 正常绑定、重复绑定 `PBL_E_DUPLICATE`、基表记录不存在 `PBL_E_NOT_FOUND`、ref_type 非法 `PBL_E_VALIDATION`、ext JSON 串与 dict 双形态 | + | `TestUnbindGetUpdate` | unbind 软删(is_deleted=1)、unbind 不存在、get_ref 正常、get_ref **跨租户返回 NOT_FOUND(不泄露存在性)**、update_ref 字段白名单 | + | `TestListRefs` | filters 组合(ref_type/blueprint_id/class_id/team_id)、分页 total/items、悬挂 ref 左连接过滤 | + | `TestTenantIsolationQueries` | list_worlds_by_tenant 仅返回本租户绑定、无绑定返回空、按 class 过滤、**list_scenes 跨租户 `PBL_E_FORBIDDEN`**、仅绑定 scene 可见、悬挂过滤 | + | `TestTeamContracts` | list_teams_by_class 成员聚合、bind_team_to_world 重复/不存在、get_team_worlds | + | `TestCheckRefAccess` | 租户匹配、班级/团队维度匹配、跨租户拒绝 | + | `TestThinExtensionInvariants` | **13 契约全部 callable**、contract_map 覆盖全部 dspy 文件、load 注册 env 函数、包导出与 init 一致、**OWN_TABLES 单表且与 models/ 一一对应**、模型四段式(summary 为数组 + UNIQUE 三元组)、**load_path 注册全部 dspy 且无通配符**、基表零 ALTER(只读投影) | +- 机械核验:`py_compile` 全部 .py = OK;dspy 审计(`grep '^import|^from' wwwroot/ --include='*.dspy'`)= 0 命中;13 个 dspy 均含显式 `return`;import 闭包实测 `CONTRACT_INTERFACES=13 missing=[]`、包 `__all__` 全可取;`grep pbl_domain_materialize_game_definition ../pbl_compiler/` = 0 命中(历史 #1 陈旧引用已不存在)。 + +## 7. 当前分支/提交状态 + +- 分支:`main`;本轮改动由引擎在交付收口时统一 commit(开发侧不自行 push)。 +- 本轮工作树新增:`docs/test-run-2026-09-18.txt`(测试执行原始输出)+ 本日志 §6/§7 追加。