@@ -16,6 +16,22 @@ from .verification_observations import ( |
| 16 | 16 | ) |
| 17 | 17 | |
| 18 | 18 | _ACTION_VERBS = ("create", "write", "make", "edit", "fix", "add", "delete", "run") |
| 19 | +_PENDING_MUTATION_HINTS = ( |
| 20 | + "create", |
| 21 | + "develop", |
| 22 | + "populate", |
| 23 | + "build", |
| 24 | + "update", |
| 25 | + "edit", |
| 26 | + "write", |
| 27 | + "fix", |
| 28 | + "modify", |
| 29 | + "change", |
| 30 | + "patch", |
| 31 | + "replace", |
| 32 | + "correct", |
| 33 | +) |
| 34 | +_PENDING_VERIFICATION_HINTS = ("verify", "validate", "test", "confirm") |
| 19 | 35 | _COMPLEX_INDICATORS = ( |
| 20 | 36 | "set up a project", |
| 21 | 37 | "create a project", |
@@ -859,6 +875,10 @@ def _build_follow_through_facts( |
| 859 | 875 | or has_planned_verification |
| 860 | 876 | or has_stale_verification |
| 861 | 877 | ) |
| 878 | + pending_items = _order_completion_pending_items( |
| 879 | + pending_items, |
| 880 | + has_recorded_work=has_recorded_work, |
| 881 | + ) |
| 862 | 882 | for evidence in dod.evidence: |
| 863 | 883 | if not evidence.passed: |
| 864 | 884 | continue |
@@ -900,6 +920,30 @@ def _first_verification_command(dod: DefinitionOfDone) -> str | None: |
| 900 | 920 | return None |
| 901 | 921 | |
| 902 | 922 | |
| 923 | +def _order_completion_pending_items( |
| 924 | + pending_items: list[str], |
| 925 | + *, |
| 926 | + has_recorded_work: bool, |
| 927 | +) -> list[str]: |
| 928 | + """Prefer concrete unfinished work when assessing premature completion.""" |
| 929 | + |
| 930 | + if not has_recorded_work: |
| 931 | + return pending_items |
| 932 | + for item in pending_items: |
| 933 | + if _pending_item_is_mutation_step(item): |
| 934 | + return [item, *(candidate for candidate in pending_items if candidate != item)] |
| 935 | + return pending_items |
| 936 | + |
| 937 | + |
| 938 | +def _pending_item_is_mutation_step(item: str) -> bool: |
| 939 | + text = item.strip().lower() |
| 940 | + if not text: |
| 941 | + return False |
| 942 | + if any(hint in text for hint in _PENDING_VERIFICATION_HINTS): |
| 943 | + return False |
| 944 | + return any(hint in text for hint in _PENDING_MUTATION_HINTS) |
| 945 | + |
| 946 | + |
| 903 | 947 | def _looks_like_verification_command(command: str) -> bool: |
| 904 | 948 | command_lower = command.lower() |
| 905 | 949 | return any( |