Files
codex-app-server/cloud/tests/test_qa_matrix.py
T
host e921db3472 audit: independent audit role, auto-pushback, rebuild branch, three tightenings, QA full-chain
Independent audit (no code, independent re-run, separate signature;
CONDITIONAL never passes; deviation needs due todo) and automatic
pushback (fail -> derived fix subtask, merge/release blocked,
package with per-item evidence, full re-audit, 3-round limit with
a separate CI auto-fix counter, ledger hash-chain interface for
track 4, gate-block interface for track 1). Over 3 failures per
module per contract version: rebuild only that module from the
frozen contract (old implementation archived, avoidance list),
contract/design root cause -> G2 re-freeze escalation instead.
Tightenings: 3rd-failure triage (structural early rebuild /
early refreeze, near-complete one targeted round), rebuild keeps
tests and passed assets with an old-test first gate, audit-of-
audit sampling/correction and G6 user-only acceptance plus
acceptance-rebuild user confirmation. QA full chain: self-test
three parts, PRD coverage, agent six, cross-client matrix with
honest uncompiled verdicts, G5 gates, impact-scoped regression,
dual QA/audit signatures, failed-link re-runs in re-audit.
Skill text is purely additive (+459/-0) against main v0.2 text;
port this section into v0.3/v0.4/v0.5 texts on merge, never
overwrite them with this file.
2026-11-03 02:49:25 +00:00

248 lines
10 KiB
Python

"""QA full-chain checks: self-test, PRD coverage, agent six,
cross-client matrix, G5 gate, regression scope, dual signatures.
Pins the seven required behaviours: (1) PRD full coverage,
(2) agent-specific six complete, (3) cross-client matrix covers
every selected client, (4) a missing client states its reason,
(5) untested is never written as passed, (6) the uncompiled
platform verdict is code-review-plus-web-core, never build-pass,
(7) defect regression follows the impact surface, not a full
retest by default. Plus: self-test three parts, consistency
classification, QA never fixing code, and the dual-signature
rule (QA matrix seat vs independent audit seat).
"""
import sys
import unittest
from pathlib import Path
try:
from cloud.qa_matrix import (
check_agent_six,
check_consistency,
check_cross_client_matrix,
check_g5,
check_prd_coverage,
check_qa_fix_role,
check_reaudit_reran_links,
check_self_test,
check_signatures,
plan_regression,
)
except ImportError:
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from cloud.qa_matrix import (
check_agent_six,
check_consistency,
check_cross_client_matrix,
check_g5,
check_prd_coverage,
check_qa_fix_role,
check_reaudit_reran_links,
check_self_test,
check_signatures,
plan_regression,
)
class SelfTestTestCase(unittest.TestCase):
def test_three_parts_required_including_smoke_steps(self):
complete, missing = check_self_test({
"unit": True, "contract_integration": True,
"manual_smoke": {"startup": True, "login": True,
"core_agent_task": True,
"error_prompt": True}})
self.assertTrue(complete)
self.assertEqual(missing, [])
_complete, missing2 = check_self_test({
"unit": True, "contract_integration": True,
"manual_smoke": {"startup": True, "login": True,
"core_agent_task": True}})
self.assertIn("manual_smoke:error_prompt", missing2)
_c3, missing3 = check_self_test({"unit": True})
self.assertIn("contract_integration", missing3)
class PrdCoverageTestCase(unittest.TestCase):
def test_every_criterion_needs_a_valid_case(self):
result = check_prd_coverage(
["prd-1", "prd-2"],
[{"id": "case-1", "covers": ["prd-1"],
"precondition": "logged in", "steps": "run task",
"expected": "result returned"}])
self.assertEqual(result["missing_criteria"], ["prd-2"])
self.assertEqual(result["invalid_cases"], [])
def test_case_without_expected_result_does_not_cover(self):
result = check_prd_coverage(
["prd-1"],
[{"id": "case-1", "covers": ["prd-1"],
"precondition": "logged in", "steps": "run task",
"expected": ""}])
self.assertEqual(result["missing_criteria"], ["prd-1"])
self.assertIn("case-1", result["invalid_cases"])
class AgentSixTestCase(unittest.TestCase):
def test_all_six_required(self):
self.assertEqual(check_agent_six({
"sandbox_escape": True,
"dangerous_action_approval": True,
"long_task_timeout_cancel": True,
"offline_resume": True,
"model_503_retry": True,
"token_quota_exceeded": True}), [])
missing = check_agent_six({"sandbox_escape": True})
self.assertEqual(len(missing), 5)
self.assertIn("token_quota_exceeded", missing)
class MatrixTestCase(unittest.TestCase):
def test_matrix_covers_every_selected_client(self):
result = check_cross_client_matrix(
["web", "ios"],
[{"client": "web", "verdict": "pass"},
{"client": "ios",
"verdict": "code_review_plus_web_core"}])
self.assertTrue(result["accounted"])
self.assertTrue(result["qa_pass"])
self.assertEqual(result["missing_clients"], [])
def test_missing_client_is_listed(self):
result = check_cross_client_matrix(
["web", "ios"],
[{"client": "web", "verdict": "pass"}])
self.assertEqual(result["missing_clients"], ["ios"])
self.assertFalse(result["accounted"])
def test_untested_with_reason_is_accounted_but_not_pass(self):
result = check_cross_client_matrix(
["web"],
[{"client": "web", "verdict": "untested",
"untested_reason": "device lab unavailable"}])
self.assertTrue(result["accounted"])
self.assertFalse(result["qa_pass"])
def test_untested_without_reason_is_neither(self):
result = check_cross_client_matrix(
["web"], [{"client": "web", "verdict": "untested"}])
self.assertFalse(result["accounted"])
self.assertFalse(result["qa_pass"])
self.assertTrue(result["violations"])
def test_uncompiled_client_cannot_claim_build_pass(self):
for client in ("ios", "android", "macos"):
with self.subTest(client=client):
result = check_cross_client_matrix(
[client], [{"client": client, "verdict": "pass"}])
self.assertFalse(result["qa_pass"])
self.assertTrue(result["violations"])
class ConsistencyTestCase(unittest.TestCase):
def test_matching_rows_are_consistent(self):
result = check_consistency([
{"client": "web", "result": "ok", "status_word": "done",
"sync_state": "synced"},
{"client": "ios", "result": "ok", "status_word": "done",
"sync_state": "synced"}])
self.assertTrue(result["consistent_or_explained"])
def test_intentional_difference_needs_a_basis(self):
result = check_consistency([
{"client": "web", "result": "ok", "status_word": "done",
"sync_state": "synced"},
{"client": "ios", "result": "ok", "status_word": "完成",
"sync_state": "synced", "classification": "intentional",
"basis": ""}])
self.assertFalse(result["consistent_or_explained"])
ok = check_consistency([
{"client": "web", "result": "ok", "status_word": "done",
"sync_state": "synced"},
{"client": "ios", "result": "ok", "status_word": "完成",
"sync_state": "synced", "classification": "intentional",
"basis": "iOS uses localised status words per design §4"}])
self.assertTrue(ok["consistent_or_explained"])
defect = check_consistency([
{"client": "web", "result": "ok", "status_word": "done",
"sync_state": "synced"},
{"client": "ios", "result": "error", "status_word": "done",
"sync_state": "synced", "classification": "defect"}])
self.assertFalse(defect["consistent_or_explained"])
class G5AndRegressionTestCase(unittest.TestCase):
def test_g5_requires_all_gates_and_no_severe_unfixed(self):
gates = {"unit": True, "integration": True,
"cross_client_consistency": True,
"agent_security": True, "long_task": True,
"performance_and_security": True}
self.assertTrue(check_g5({"gates": gates, "failures": []})["g5_pass"])
missing = check_g5({"gates": dict(gates, long_task=False),
"failures": []})
self.assertIn("long_task", missing["missing_gates"])
blocked = check_g5({
"gates": gates,
"failures": [{"severity": "severe", "fixed": False,
"owner": "web", "reproduction": "run X"}]})
self.assertFalse(blocked["g5_pass"])
self.assertEqual(len(blocked["blocking_defects"]), 1)
def test_regression_follows_impact_surface_not_full_retest(self):
cases = [{"id": "c-a", "covers": ["contract-A"]},
{"id": "c-b", "covers": ["contract-B"]}]
plan = plan_regression(["contract-A"], cases)
self.assertEqual(plan["regression_cases"], ["c-a"])
self.assertFalse(plan["is_full_retest"])
self.assertEqual(plan["uncovered_areas"], [])
uncovered = plan_regression(["contract-C"], cases)
self.assertEqual(uncovered["uncovered_areas"], ["contract-C"])
def test_qa_must_not_fix_code_directly(self):
self.assertTrue(check_qa_fix_role(
[{"defect": "d-1", "fixed_by": "qa"}]))
self.assertEqual(check_qa_fix_role(
[{"defect": "d-1", "fixed_by": "client-web"}]), [])
class SignaturesAndReauditTestCase(unittest.TestCase):
def test_dual_signature_seats_both_required_and_distinct(self):
self.assertEqual(check_signatures("qa-q", "auditor-a"), [])
self.assertTrue(check_signatures("qa-q", None))
self.assertTrue(check_signatures(None, "auditor-a"))
self.assertTrue(check_signatures("same", "same"))
def test_reaudit_must_rerun_failed_links(self):
package = {"reaudit_must_rerun_links": ["link-create-task",
"link-cancel-task"]}
ok = check_reaudit_reran_links(
package, {"link-create-task": True, "link-cancel-task": True})
self.assertTrue(ok["reran_all_failed_links"])
missing = check_reaudit_reran_links(
package, {"link-create-task": True})
self.assertFalse(missing["reran_all_failed_links"])
self.assertIn("link-cancel-task", missing["missing"])
failed = check_reaudit_reran_links(
package, {"link-create-task": True,
"link-cancel-task": False})
self.assertIn("link-cancel-task", failed["failed"])
class QaSkillTextTestCase(unittest.TestCase):
def test_qa_section_present_in_skill(self):
skill = Path(__file__).resolve().parents[1] / "skills" \
/ "software-engineering" / "SKILL.md"
text = skill.read_text(encoding="utf-8")
for phrase in (
"QA 全链路",
"agent 专属六项",
"跨端矩阵",
"代码评审 + Web 核心验证",
):
with self.subTest(phrase=phrase):
self.assertIn(phrase, text)
if __name__ == "__main__":
unittest.main()