"""v7 机制第 2 项:三张表拆分定向测试。 维分配(与 cloud/audit_scorecard.py 的注释一致): - 代码表:delivery_quality、gate_audit、arch_contract、test_coverage (代码证据,不含生产项)。 - 生产表:security_ledger、cost_quota、ops_scale(生产证据)。 - 产品表:全部 7 维 + 真实产品轮门禁;无真实产品轮证据时恒 not_pass, 这只是评分卡输入结构拆分,不代表任何产品功能已落地。 钉住的规则: - 代码表 overall 独立:生产证据缺失、B/C 用户侧项 pending, 都不拉低代码表。 - 生产表缺项不拉低代码表;生产表 overall 独立,平均分不作依据。 - 三张表各自 average_is_not_pass_criterion=True。 - 阈值默认值一律 test_default_unapproved,未拍板。 - 端点 GET /audit-scorecard 返回的示例卡带 code/production/product 三个子对象(端点已接线,非冒充)。 """ import http.client import json import os import sys import tempfile import threading import unittest from pathlib import Path try: from cloud.audit_scorecard import ( CODE_DIMENSION_IDS, DEFAULT_THRESHOLDS, PRODUCTION_DIMENSION_IDS, PRODUCT_DIMENSION_IDS, build_code_scorecard, build_product_scorecard, build_production_scorecard, build_scorecard, example_scorecard_as_of_2026_10_31) from cloud.auth import AuthStore from cloud.server import create_server except ImportError: sys.path.insert(0, str(Path(__file__).resolve().parents[2])) from cloud.audit_scorecard import ( CODE_DIMENSION_IDS, DEFAULT_THRESHOLDS, PRODUCTION_DIMENSION_IDS, PRODUCT_DIMENSION_IDS, build_code_scorecard, build_product_scorecard, build_production_scorecard, build_scorecard, example_scorecard_as_of_2026_10_31) from cloud.auth import AuthStore from cloud.server import create_server def _code_evidence(): return { "delivery_quality": { "first_pass_rate": 0.96, "defect_rate": 0.01, "rework_rate": 0.04, "first_pass_known": True, "defect_known": True, "rework_known": True, "attempts_present": True, "evidence_kind": "real", }, "gate_audit": { "hard_gate_enforced": True, "gate_items_passed": 5, "gate_items_total": 5, "merge_blocked_verified": True, "loop_end_to_end_verified": True, "sampling_misjudgment_rate": 0.0, }, "arch_contract": { "contract_frozen": True, "arch_violations": 0, "directory_violations": 0, "import_violations": 0, "stack_changed_without_approval": False, }, "test_coverage": { "prd_coverage_rate": 1.0, "cross_matrix_coverage_rate": 1.0, "coverage_pct": 0.92, "cross_matrix_kind": "real", "real_pg": True, "real_service": True, "agent_six_complete": True, "lint_items": 0, "mypy_items": 0, "bandit_high": 0, }, } def _production_evidence(): return { "security_ledger": { "ledger_verify_ok": True, "ledger_coverage_rate": 1.0, "branch_protection": "protected", "shell_whitelist_pass_rate": 1.0, "anchor_check_recent": True, }, "cost_quota": { "cost_records_complete": True, "unpriced_as_zero": False, "per_creator_present": True, "quota_cutoff_verified": True, }, "ops_scale": { "ci_green_rate": 1.0, "deploy_success_rate": 1.0, "rollback_drill_done": True, "ha_status": "second_host", "parallel_scale_proven": 40, }, } def _full_evidence(): ev = {} ev.update(_code_evidence()) ev.update(_production_evidence()) return ev def _product_evidence(): return { "real_product_round": True, "real_app_installed": True, "real_user_flow_verified": True, "product_round_as_of": "2026-11-02", } class SplitTablesTestCase(unittest.TestCase): def test_dimension_allocation_is_pinned(self): self.assertEqual(CODE_DIMENSION_IDS, [ "delivery_quality", "gate_audit", "arch_contract", "test_coverage"]) self.assertEqual(PRODUCTION_DIMENSION_IDS, [ "security_ledger", "cost_quota", "ops_scale"]) self.assertEqual(PRODUCT_DIMENSION_IDS, [ "delivery_quality", "gate_audit", "arch_contract", "test_coverage", "security_ledger", "cost_quota", "ops_scale"]) self.assertFalse(set(CODE_DIMENSION_IDS) & set(PRODUCTION_DIMENSION_IDS)) def test_code_table_passes_on_code_evidence_alone(self): table = build_code_scorecard(_code_evidence()) self.assertEqual(table["overall"], "pass") self.assertTrue(table["overall_pass"]) self.assertEqual([d["id"] for d in table["dimensions"]], CODE_DIMENSION_IDS) self.assertTrue(table["average_is_not_pass_criterion"]) self.assertEqual(table["thresholds_source"], "test_default_unapproved") for dim in table["dimensions"]: self.assertGreaterEqual(dim["score"], 9.0) def test_bc_all_pending_code_passes_production_not_pass(self): # 核心验收:B/C 全 pending 时代码表仍可 pass、生产表 not_pass。 # user_side_items 在此只是占位证据,不依赖第 7 项的代码。 user_side = [{"id": "B", "status": "pending"}, {"id": "C", "status": "pending"}] code = build_code_scorecard(_full_evidence()) prod = build_production_scorecard( _full_evidence(), user_side_items=user_side) self.assertEqual(code["overall"], "pass") self.assertEqual(prod["overall"], "not_pass") self.assertFalse(prod["overall_pass"]) self.assertTrue(prod["user_side_blocked"]) self.assertEqual([p["id"] for p in prod["user_side_pending"]], ["B", "C"]) self.assertTrue(any("B" in m for m in prod["missing_items"])) self.assertTrue(any("C" in m for m in prod["missing_items"])) # 挡住 overall 但不篡改维分数:生产维本身仍全 >=9。 for dim in prod["dimensions"]: self.assertGreaterEqual(dim["score"], 9.0) def test_bc_pending_in_dict_and_string_forms_also_blocks(self): prod = build_production_scorecard( _full_evidence(), user_side_items={"B": "pending"}) self.assertEqual(prod["overall"], "not_pass") prod2 = build_production_scorecard( _full_evidence(), user_side_items=["B"]) self.assertEqual(prod2["overall"], "not_pass") def test_production_missing_evidence_does_not_lower_code_table(self): # 生产证据直接缺失(不传 user_side_items 也一样):生产表 # not_pass,代码表仍 pass——缺项不跨表拉低。 code = build_code_scorecard(_code_evidence()) prod = build_production_scorecard(_code_evidence()) self.assertEqual(code["overall"], "pass") self.assertEqual(prod["overall"], "not_pass") for dim in prod["dimensions"]: self.assertIsNone(dim["score"]) self.assertEqual(dim["status"], "unknown") def test_production_passes_when_evidence_full_and_user_side_done(self): prod = build_production_scorecard( _full_evidence(), user_side_items=[{"id": "B", "status": "done"}, {"id": "C", "status": "approved"}]) self.assertEqual(prod["overall"], "pass") self.assertFalse(prod["user_side_blocked"]) self.assertEqual(prod["user_side_pending"], []) def test_product_table_without_real_round_is_always_not_pass(self): # 无真实产品轮证据:即使代码+生产证据全满,产品表也恒 not_pass, # 全部维 None——绝不把代码/生产分数冒充成产品分数。 table = build_product_scorecard(_full_evidence()) self.assertEqual(table["overall"], "not_pass") self.assertFalse(table["product_gate_passed"]) for dim in table["dimensions"]: self.assertIsNone(dim["score"]) self.assertEqual(dim["status"], "unknown") self.assertTrue(table["product_round_missing_fields"]) def test_product_table_with_real_round_scores_same_dimensions(self): table = build_product_scorecard(_full_evidence(), product_evidence=_product_evidence()) self.assertTrue(table["product_gate_passed"]) self.assertEqual(table["overall"], "pass") self.assertEqual(len(table["dimensions"]), 7) for dim in table["dimensions"]: self.assertGreaterEqual(dim["score"], 9.0) def test_product_average_91_with_one_four_still_fails(self): # 产品表平均分规则:6 维 10 分、1 维 4 分,平均 9.1,仍 not_pass。 ev = _full_evidence() ev["gate_audit"]["hard_gate_enforced"] = False table = build_product_scorecard(ev, product_evidence=_product_evidence()) self.assertEqual(table["average_score"], 9.1) self.assertTrue(table["average_is_not_pass_criterion"]) self.assertEqual(table["overall"], "not_pass") def test_build_scorecard_carries_three_subobjects(self): report = build_scorecard( _full_evidence(), user_side_items=[{"id": "B", "status": "pending"}, {"id": "C", "status": "pending"}]) # 旧字段语义不变:7 维全满时旧 overall 仍 pass。 self.assertEqual(report["overall"], "pass") self.assertEqual(len(report["dimensions"]), 7) self.assertEqual(report["code"]["overall"], "pass") self.assertEqual(report["production"]["overall"], "not_pass") # 产品表无真实产品轮证据,恒 not_pass。 self.assertEqual(report["product"]["overall"], "not_pass") self.assertEqual([d["id"] for d in report["code"]["dimensions"]], CODE_DIMENSION_IDS) self.assertEqual( [d["id"] for d in report["production"]["dimensions"]], PRODUCTION_DIMENSION_IDS) def test_example_card_carries_three_subobjects_all_not_pass(self): report = example_scorecard_as_of_2026_10_31() self.assertEqual(report["overall"], "not_pass") self.assertEqual(report["code"]["overall"], "not_pass") self.assertEqual(report["production"]["overall"], "not_pass") self.assertEqual(report["product"]["overall"], "not_pass") self.assertFalse(report["product"]["product_gate_passed"]) def test_threshold_defaults_still_unapproved_in_all_tables(self): for entry in DEFAULT_THRESHOLDS.values(): self.assertEqual(entry["source"], "test_default_unapproved") for table in (build_code_scorecard(_full_evidence()), build_production_scorecard(_full_evidence()), build_product_scorecard(_full_evidence(), product_evidence=_product_evidence())): self.assertEqual(table["thresholds_source"], "test_default_unapproved") class SplitTablesEndpointTestCase(unittest.TestCase): def setUp(self): self.tmp = tempfile.TemporaryDirectory() self.db_path = os.path.join(self.tmp.name, "control.db") self.auth = AuthStore(self.db_path) self.owner_id, self.owner_key = self.auth.create_user("owner") self.server = create_server(self.db_path, "127.0.0.1", 0) self.port = self.server.server_address[1] self.thread = threading.Thread( target=self.server.serve_forever, daemon=True) self.thread.start() def tearDown(self): self.server.shutdown() self.server.server_close() self.thread.join(timeout=5) try: self.auth.conn.close() except Exception: pass self.tmp.cleanup() def test_endpoint_returns_three_subobjects(self): conn = http.client.HTTPConnection("127.0.0.1", self.port, timeout=10) try: conn.request("GET", "/audit-scorecard", headers={"X-API-Key": self.owner_key}) resp = conn.getresponse() report = json.loads(resp.read().decode("utf-8")) finally: conn.close() self.assertEqual(resp.status, 200) self.assertEqual(report["overall"], "not_pass") for key in ("code", "production", "product"): self.assertIn(key, report) self.assertEqual(report[key]["overall"], "not_pass") self.assertEqual(len(report["code"]["dimensions"]), 4) self.assertEqual(len(report["production"]["dimensions"]), 3) self.assertEqual(len(report["product"]["dimensions"]), 7) if __name__ == "__main__": unittest.main()