(argv: Sequence[str])
| 489 | |
| 490 | |
| 491 | def main(argv: Sequence[str]) -> None: |
| 492 | args = parse_arguments(argv) |
| 493 | output = args.out_dir |
| 494 | if output.name in ("", ".", ".."): |
| 495 | raise ContractError(f"unsafe output directory: {output}") |
| 496 | if os.path.lexists(output): |
| 497 | raise ContractError(f"refusing to overwrite output path: {output}") |
| 498 | |
| 499 | candidates, object_paths = load_candidates(args.candidates, args.objects_dir) |
| 500 | results = load_results(args.results, candidates) if args.results else None |
| 501 | policy = "virustotal-v2" if results is not None else "unscanned-dry-run" |
| 502 | candidate_by_tuple = { |
| 503 | (row["target"], row["variant"]): row for row in candidates |
| 504 | } |
| 505 | |
| 506 | output.parent.mkdir(parents=True, exist_ok=True) |
| 507 | temporary = pathlib.Path( |
| 508 | tempfile.mkdtemp(prefix=f".{output.name}.select-", dir=str(output.parent)) |
| 509 | ) |
| 510 | staged = temporary / "bundle" |
| 511 | staged.mkdir(mode=0o700) |
| 512 | selection_rows: list[dict[str, object]] = [] |
| 513 | try: |
| 514 | for target in TARGETS: |
| 515 | pair = { |
| 516 | variant: candidate_by_tuple[target, variant] for variant in VARIANTS |
| 517 | } |
| 518 | if results is None: |
| 519 | classifications = { |
| 520 | variant: "unscanned-dry-run" for variant in VARIANTS |
| 521 | } |
| 522 | selected_variant = "stripped" |
| 523 | decision = "stripped-unscanned-dry-run" |
| 524 | else: |
| 525 | classifications = { |
| 526 | variant: results[pair[variant]["scan_path"]]["policy_classification"] |
| 527 | for variant in VARIANTS |
| 528 | } |
| 529 | # Preference order is fixed and content-independent: the |
| 530 | # smallest artifact first, then progressively more metadata. |
| 531 | # A `hard` classification never reaches here - the gate fails |
| 532 | # the release before selection - so every candidate below is |
| 533 | # either clean or a tolerated single Microsoft `!ml`. |
| 534 | # |
| 535 | # The variants are behaviourally identical, so this picks on |
| 536 | # verdict alone: the first clean one in preference order, and |
| 537 | # only if EVERY candidate drew the tolerated verdict do we ship |
| 538 | # a flagged one (still the smallest). |
| 539 | order = ("stripped", "debug-stripped", "unstripped") |
| 540 | clean = [v for v in order if classifications[v] == "clean"] |
| 541 | if clean: |
| 542 | selected_variant = clean[0] |
| 543 | if selected_variant == "stripped": |
| 544 | decision = "stripped-preferred" |
| 545 | else: |
| 546 | others = "-".join( |
| 547 | f"{v}:{classifications[v]}" for v in order if v != selected_variant |
| 548 | ) |
no test coverage detected