feat: release 2.2.0 with PC-only tests and execution reliability fixes

Unify task scheduling and queue state, fix Android input and observation recovery, preserve screenshot paths, and match final review criteria accurately. Add collapsible copyable results and publish the complete 2.1.0 upgrade notes. Validation: 3189 backend tests, 326 frontend tests, 24 client tests, production build and quality gates.
This commit is contained in:
chenmingxuan committed 2026-10-27 01:13:41 +08:00
1 parent fac4ccb760
commit be6e8c2abd
79 files changed
+2263 -277

No files matched your search

+72
View File
@@ -144,6 +144,78 @@ def test_normalize_report_downgrades_vague_failures_and_fills_missing():
# --- Assembly: prompt segments x entry x content x config (§8 item 18) ---------------
@pytest.mark.parametrize("kind,when", [("verify", "on_complete"), ("assert", "at_end")])
@pytest.mark.parametrize("status", ["passed", "failed", "inconclusive"])
@pytest.mark.parametrize("bullet", ["", "- "])
def test_rendered_check_label_matches_original_without_changing_verdict(kind, when, status, bullet):
item = _ci(kind=kind, when=when, text="截图路径与回执一致")
verdict = CheckVerdict(
kind=kind,
item_text=f"{bullet}[{kind}] ({when}) {item.text}",
status=status,
evidence="截图与笔记回执",
suggestion="保留原建议",
)
normalized = _normalize_report(CheckReport(verdicts=[verdict]), [item])
assert [v.model_dump() for v in normalized.verdicts] == [
{**verdict.model_dump(), "item_text": item.text}
]
assert verdict.item_text != item.text # The original response is not rewritten.
@pytest.mark.parametrize(
"kind,text",
[
("assert", "[verify] (on_complete) 截图有效"),
("verify", "[assert] (on_complete) 截图有效"),
("verify", "[verify] (at_end) 截图有效"),
("verify", "[verify] (on_complete) 截图无效"),
("verify", "[verify] (on_complete) 截图有效。"),
],
)
def test_unmatched_label_does_not_cover_declared_check(kind, text):
item = _ci(text="截图有效")
verdict = CheckVerdict(kind=kind, item_text=text, status="passed", evidence="e")
normalized = _normalize_report(CheckReport(verdicts=[verdict]), [item])
assert normalized.verdicts[0] == verdict
assert normalized.verdicts[1].item_text == item.text
assert normalized.verdicts[1].status == "inconclusive"
def test_literal_criterion_takes_precedence_over_another_items_display_label():
plain = _ci(text="截图有效")
literal = _ci(text="[verify] (on_complete) 截图有效")
verdict = CheckVerdict(kind="verify", item_text=literal.text, status="passed", evidence="e")
normalized = _normalize_report(CheckReport(verdicts=[verdict]), [plain, literal])
assert [(v.item_text, v.status) for v in normalized.verdicts] == [
(literal.text, "passed"),
(plain.text, "inconclusive"),
]
def test_conflicting_plain_and_label_verdicts_keep_the_failure():
item = _ci(text="截图有效")
normalized = _normalize_report(
CheckReport(
verdicts=[
CheckVerdict(kind="verify", item_text=item.text, status="passed", evidence="e1"),
CheckVerdict(
kind="verify",
item_text="[verify] (on_complete) 截图有效",
status="failed",
evidence="e2",
),
]
),
[item],
)
assert [(v.item_text, v.status) for v in normalized.verdicts] == [
(item.text, "passed"),
(item.text, "failed"),
]
assert not verdicts_allow_release(normalized)
def test_prompt_segments_verify_only_has_no_assert_section():
prompts = {
"base_rules": "BASE",