"""The verification test-case taxonomy: ``case_type`` -> ground-truth verdict. Each :class:`CaseSpec` encodes one row of the signature-verification test plan: what should actually be rendered into the target signature box (``signature_mode``), whether a companion box on the same page should also be filled with its own correctly-authorized signature (``fill_companion`` -- only meaningful for the multi-signer-context cases), and the ground-truth ``verdict``/``reject_code`` a downstream verifier is expected to produce. Driven by the existing ``quality.case_type`` config field (see ``configs/examples/hard_degraded.yaml`` for its prior, simpler use as a plain metadata label) -- setting it to one of the codes below switches :meth:`~src.generator.GeneratorContext.run_sample` into scenario-driven generation. Any other value (or ``None``) leaves generation entirely unaffected. """ from __future__ import annotations from dataclasses import dataclass SignatureMode = str # one of the _SIGNATURE_MODES below, kept as a plain str for simplicity NO_SIGNATURE = "NO_SIGNATURE" IDENTITY_MISMATCH = "IDENTITY_MISMATCH" ROLE_MISMATCH = "ROLE_MISMATCH" REQUIRED_SIGNER_ABSENT = "REQUIRED_SIGNER_ABSENT" @dataclass(frozen=True) class CaseSpec: """One row of the verification test-case taxonomy.""" code: str description: str verdict: str # "PASS" | "REJECT" reject_code: "str | None" signature_mode: SignatureMode fill_companion: bool = False CASE_TABLE: dict[str, CaseSpec] = { "1a": CaseSpec("1a", "Correct signer signs normally", "PASS", None, "genuine_correct"), "1b": CaseSpec("1b", "Correct signer, natural pen variation applied", "PASS", None, "genuine_variation"), "1c": CaseSpec("1c", "Multi-signer form, both sign correctly", "PASS", None, "genuine_correct", fill_companion=True), "1d": CaseSpec("1d", "Correct signer, scan degraded to test robustness", "PASS", None, "genuine_correct"), "2a": CaseSpec("2a", "Box left completely blank", "REJECT", NO_SIGNATURE, "blank"), "2b": CaseSpec("2b", "Printed/typed name only, no handwriting", "REJECT", NO_SIGNATURE, "printed_text"), "3a": CaseSpec("3a", "Wrong real person signs the box", "REJECT", IDENTITY_MISMATCH, "wrong_signer_genuine"), "3b": CaseSpec("3b", "Skilled-forgery sample used", "REJECT", IDENTITY_MISMATCH, "forged_skilled"), "4a": CaseSpec("4a", "Authorized signer, but wrong role's box", "REJECT", ROLE_MISMATCH, "role_swap", fill_companion=True), "4b": CaseSpec("4b", "Signer from a different form entirely", "REJECT", ROLE_MISMATCH, "foreign_template_signer", fill_companion=True), "5a": CaseSpec("5a", "Required signer's box left empty", "REJECT", REQUIRED_SIGNER_ABSENT, "blank", fill_companion=True), "5b": CaseSpec("5b", "Someone else signs in the required signer's place", "REJECT", REQUIRED_SIGNER_ABSENT, "wrong_signer_genuine", fill_companion=True), }