diff --git a/solstone/observe/processing_record.py b/solstone/observe/processing_record.py index 34df778dc..787742b5c 100644 --- a/solstone/observe/processing_record.py +++ b/solstone/observe/processing_record.py @@ -115,18 +115,21 @@ def jsonl_has_row_with_key(path: Path, row_key: str) -> bool: return False -# an existing analysis output only blocks re-entry when it actually carries -# evidence — analyzed rows or a processing record. An output with neither is -# indeterminate, and indeterminate work re-enters until the record ledger can -# govern it. Decode-determined verdicts terminalize regardless of provider -# availability. def should_reenter_analysis_output( *, record: dict | None, output_path: Path, handler: str, ) -> bool: - """Return whether an existing analysis output should be retried.""" + """Return whether an existing analysis output should be retried. + + an existing analysis output only blocks re-entry when it actually carries + evidence — analyzed rows or a processing record. An output with neither is + indeterminate, and indeterminate work re-enters until the record ledger can + govern it. Decode-determined verdicts terminalize regardless of provider + availability only when there is no frame-description work left to do; a run + that still has qualified frames defers instead of discarding them. + """ if ( isinstance(record, dict) and record.get("state") == STATE_FAILED diff --git a/tests/test_data_state.py b/tests/test_data_state.py index 8ec190bba..8e5ce2049 100644 --- a/tests/test_data_state.py +++ b/tests/test_data_state.py @@ -310,7 +310,7 @@ def test_ac8_screen_disagreement_table_has_no_silent_nonterminal_wedge( "reentry": True, }, { - "name": "retryable_record_marker_rows", + "name": "retryable_record_failed_marker_analysis_rows", "jsonl": True, "record": retryable_record, "rows": True, @@ -372,7 +372,7 @@ def test_ac8_screen_disagreement_table_has_no_silent_nonterminal_wedge( "reentry": False, }, { - "name": "analyzed_record_marker_rows", + "name": "analyzed_record_failed_marker_analysis_rows", "jsonl": True, "record": analyzed_record, "rows": True, @@ -393,6 +393,9 @@ def test_ac8_screen_disagreement_table_has_no_silent_nonterminal_wedge( for index, case in enumerate(cases): if case.get("impossible"): assert isinstance(case["impossible"], str) + assert case["impossible"].strip() + assert "state" not in case + assert "reentry" not in case continue assert case["jsonl"] or not case["record"] diff --git a/tests/test_sense.py b/tests/test_sense.py index 748d873c4..adf94af31 100644 --- a/tests/test_sense.py +++ b/tests/test_sense.py @@ -894,7 +894,9 @@ def test_process_day_reenters_only_retryable_describe_failures(tmp_path, monkeyp sensor.process_day("20250101", max_jobs=1) - assert processed == [case[0] for case in cases if case[-1]] + assert processed == [ + segment for segment, _record, _rows, expected in cases if expected + ] def test_process_day_reentry_uses_bounded_first_window(tmp_path, monkeypatch):