| 1 | """Evidence requirements for publishing output-usefulness measurements.
|
| 2 |
|
| 3 | Legacy structural markers remain diagnostic data. They cannot certify that
|
| 4 | standard patch tooling reconstructs the intended repository tree.
|
| 5 | """
|
| 6 |
|
| 7 | from __future__ import annotations
|
| 8 |
|
| 9 | from typing import Any
|
| 10 | import math
|
| 11 | import re
|
| 12 | import json
|
| 13 |
|
| 14 | from oakbench.rows import row_returncode
|
| 15 | from oakbench.populations import comparison_identity
|
| 16 | from oakbench.output_semantics import OUTPUT_ORACLE_VERSION, PATCH_ORACLE_VERSION
|
| 17 | from oakbench.workflow_oracles import SCENARIOS as TRUSTED_WORKFLOWS, VERSION as WORKFLOW_ORACLE_VERSION
|
| 18 |
|
| 19 |
|
| 20 | def output_evidence_failures(row: dict[str, Any]) -> list[str]:
|
| 21 | failures: list[str] = []
|
| 22 | for flag in ("pipe_compatible_unified", "patch_apply_ok", "patch_tree_matches", "patch_application_required"):
|
| 23 | if row.get(flag) is not None and type(row[flag]) is not bool:
|
| 24 | failures.append(f"{flag} is not a nullable boolean")
|
| 25 | for metric, source in (
|
| 26 | ("information_recall", "information_recall_source"),
|
| 27 | ("information_precision", "information_precision_source"),
|
| 28 | ):
|
| 29 | value = row.get(metric)
|
| 30 | if value is not None and (
|
| 31 | type(value) not in (int, float) or not math.isfinite(value) or not 0 <= value <= 1
|
| 32 | ):
|
| 33 | failures.append(f"{metric} is not a finite fraction")
|
| 34 | if row.get(metric) is not None and (row.get("output_truncated") is True or row.get("probe_output_truncated") is True):
|
| 35 | failures.append(f"{metric} is measured from incomplete output")
|
| 36 | if row.get(metric) is not None and (
|
| 37 | row.get("output_oracle_version") != OUTPUT_ORACLE_VERSION
|
| 38 | or row.get(source) != "exact_metadata_path_set"
|
| 39 | ):
|
| 40 | failures.append(f"{metric} lacks versioned exact-path evidence")
|
| 41 |
|
| 42 | claims_applicability = row.get("patch_application_required") is True or row.get("patch_apply_ok") is True
|
| 43 | if claims_applicability and not (
|
| 44 | row.get("patch_apply_ok") is True
|
| 45 | and row.get("patch_tree_matches") is True
|
| 46 | and row.get("patch_apply_returncode") == 0
|
| 47 | and type(row.get("patch_apply_returncode")) is int
|
| 48 | and row.get("patch_oracle_version") == PATCH_ORACLE_VERSION
|
| 49 | and row.get("patch_apply_source") == "git_apply_exact_tree"
|
| 50 | and isinstance(row.get("patch_instrument_sha256"), str)
|
| 51 | and re.fullmatch(r"[0-9a-f]{64}", row["patch_instrument_sha256"])
|
| 52 | and isinstance(row.get("patch_instrument_version"), str)
|
| 53 | and row["patch_instrument_version"].strip()
|
| 54 | and not row.get("patch_skip_reason")
|
| 55 | and not row.get("patch_failure_reason")
|
| 56 | and not row.get("probe_output_truncated")
|
| 57 | and not row.get("output_truncated")
|
| 58 | ):
|
| 59 | failures.append("structural/applicability success lacks a successful exact-tree patch application")
|
| 60 | return failures
|
| 61 |
|
| 62 |
|
| 63 | def workflow_evidence_failures(rows: list[dict[str, Any]]) -> list[str]:
|
| 64 | """Require independent persisted-state evidence for trusted payload tasks.
|
| 65 |
|
| 66 | Source labels describe how observations were obtained; they are not
|
| 67 | equivalence classes. Scripted summaries must pass; measured agent failures
|
| 68 | remain evidence for success-rate accounting.
|
| 69 | Successful comparisons require the shared committed-content contract.
|
| 70 | """
|
| 71 | groups = {}
|
| 72 | failures = []
|
| 73 | for row in rows:
|
| 74 | operation = row.get("operation")
|
| 75 | if operation not in {"agent.workflow", "workflow.total", "workflow.skipped"}:
|
| 76 | continue
|
| 77 | code = row_returncode(row)
|
| 78 | integrity = row.get("workflow_integrity_passed")
|
| 79 | measured_agent_failure = (
|
| 80 | operation == "agent.workflow" and type(integrity) is bool
|
| 81 | and row.get("outcome") in {"fail", "timeout", "error"}
|
| 82 | and row.get("success") is False and code not in {0, 77}
|
| 83 | and not row.get("skipped")
|
| 84 | and row.get("outcome_attribution") == "agent" and row.get("agent_launched") is True
|
| 85 | )
|
| 86 | if not measured_agent_failure and (
|
| 87 | operation == "workflow.skipped" or integrity is not True or code != 0
|
| 88 | or row.get("skipped") or row.get("success") is False
|
| 89 | or row.get("correctness_passed") is False
|
| 90 | or (operation == "agent.workflow" and row.get("outcome") not in {None, "pass"})
|
| 91 | ):
|
| 92 | failures.append(f"{row.get('subject')}/{row.get('scenario')}: workflow correctness is failed, skipped or unmeasured")
|
| 93 | if row.get("operation") in {"agent.workflow", "workflow.total"} and row.get("workflow_integrity_evidence_class") in {"independent_committed_tree", "independent_committed_payload"}:
|
| 94 | if row.get("workflow_integrity_source") == "trusted_task_worktree;independent_oak_sqlite_reader":
|
| 95 | from oakbench.oak_sqlite_reader import READER_VERSION
|
| 96 | valid = row.get("oak_reader_version") == READER_VERSION
|
| 97 | valid = valid and all(isinstance(row.get(field), str) and re.fullmatch(r"[0-9a-f]{64}", row[field])
|
| 98 | for field in ("oak_reader_sha256", "oak_reader_head", "oak_reader_python_sha256"))
|
| 99 | valid = valid and all(isinstance(row.get(field), str) and row[field].strip()
|
| 100 | for field in ("oak_reader_blake3_version", "oak_reader_zstandard_version"))
|
| 101 | if not valid:
|
| 102 | failures.append("independent Oak reader lacks versioned instrument/object evidence")
|
| 103 | else:
|
| 104 | instrument = row.get("git_head_instrument_sha256")
|
| 105 | subject = row.get("workflow_subject_binary_sha256")
|
| 106 | if (not all(isinstance(value, str) and re.fullmatch(r"[0-9a-f]{64}", value) for value in (instrument, subject))
|
| 107 | or instrument == subject or "subject_produced" in str(row.get("workflow_integrity_source", ""))):
|
| 108 | failures.append("independent reader lacks distinct observed subject/instrument identities or uses subject-produced evidence")
|
| 109 | agent = row.get("agent") if isinstance(row.get("agent"), dict) else {}
|
| 110 | key = (row.get("scenario"), "workflow.total" if operation == "workflow.skipped" else operation)
|
| 111 | groups.setdefault(key, []).append(row)
|
| 112 | for key, items in groups.items():
|
| 113 | if len({item.get("subject") for item in items}) < 2:
|
| 114 | continue
|
| 115 | conditions = {}
|
| 116 | for item in items:
|
| 117 | agent = item.get("agent") if isinstance(item.get("agent"), dict) else {}
|
| 118 | condition = comparison_identity(item)
|
| 119 | condition.pop("workflow_integrity_evidence_class", None) # failed pre-HEAD observations remain task failures
|
| 120 | condition["agent.name"] = agent.get("name")
|
| 121 | conditions.setdefault(item.get("subject"), set()).add(json.dumps(condition, sort_keys=True))
|
| 122 | if len({tuple(sorted(values)) for values in conditions.values()}) != 1:
|
| 123 | failures.append(f"{key}: subjects have unmatched experimental conditions")
|
| 124 | verified = [item for item in items if item.get("workflow_integrity_passed") is True]
|
| 125 | if len({item.get("workflow_integrity_evidence_class") for item in verified}) > 1:
|
| 126 | failures.append(f"{key}: successful subjects have unequal correctness evidence classes")
|
| 127 | if any(item.get("oracle_version") != WORKFLOW_ORACLE_VERSION for item in items):
|
| 128 | failures.append(f"{key}: trusted task validator version is incompatible or missing")
|
| 129 | # Failed task validation can finish before any HEAD reader runs. It
|
| 130 | # measures failure, not persisted completion; keep those trials in
|
| 131 | # success-rate evidence without inventing an independent reader.
|
| 132 | if any(item.get("workflow_integrity_evidence_class") not in {"independent_committed_tree", "independent_committed_payload"} for item in items
|
| 133 | if not (item.get("operation") == "agent.workflow" and item.get("workflow_integrity_passed") is False)):
|
| 134 | failures.append(f"{key}: trusted persisted-state comparison requires independent committed-tree readers; subject-produced exports and metadata are insufficient")
|
| 135 | if any(not isinstance(item.get("workflow_integrity_source"), str) or not item["workflow_integrity_source"].strip() for item in items):
|
| 136 | failures.append(f"{key}: correctness evidence source is missing")
|
| 137 | if any("subject_produced" in str(item.get("workflow_integrity_source", ""))
|
| 138 | and item.get("workflow_integrity_evidence_class") in {"independent_committed_tree", "independent_committed_payload"} for item in items):
|
| 139 | failures.append(f"{key}: subject-produced evidence cannot declare an independent reader class")
|
| 140 | if any(type(item.get("workflow_integrity_passed")) is not bool for item in items):
|
| 141 | failures.append(f"{key}: correctness evidence is failed or unmeasured")
|
| 142 | return failures
|
| 143 |
|
| 144 |
|
| 145 | def workflow_qualification_failures(rows: list[dict[str, Any]], min_samples: int = 30) -> list[str]:
|
| 146 | """Necessary publication hygiene, not a power calculation or study certification."""
|
| 147 | selected = [row for row in rows if row.get("operation") in {"workflow.total", "workflow.skipped", "agent.workflow", "agent.setup"}]
|
| 148 | failures = []
|
| 149 | if not selected:
|
| 150 | return failures
|
| 151 | values = [row.get("env_isolation_version") for row in selected]
|
| 152 | versions = {value for value in values if isinstance(value, str)}
|
| 153 | if len(versions) != 1 or any(not isinstance(value, str) or not value.strip() or value in {"unknown", "unmeasured"} for value in values):
|
| 154 | failures.append("workflow env-isolation is missing or inconsistent")
|
| 155 | groups = {}
|
| 156 | for row in selected:
|
| 157 | failures.extend(output_evidence_failures(row))
|
| 158 | if row.get("operation") == "agent.setup":
|
| 159 | failures.append("agent setup infrastructure failure cannot qualify a study")
|
| 160 | randomized = next((row[name] for name in ("randomized_subject_order", "randomize_subject_order", "subject_order_randomized") if name in row), None)
|
| 161 | order = row.get("subject_order", row.get("run_subject_order"))
|
| 162 | if randomized is not True or not isinstance(order, list) or row.get("subject") not in order:
|
| 163 | failures.append("workflow subject randomization/order is unmeasured")
|
| 164 | agent = row.get("agent") if isinstance(row.get("agent"), dict) else {}
|
| 165 | key = (row.get("scenario"), row.get("operation"), row.get("subject"), row.get("benchmark_track"),
|
| 166 | row.get("instruction_level", agent.get("instruction_level")), json.dumps(agent, sort_keys=True))
|
| 167 | identity = (row.get("bench_id"), row.get("run"))
|
| 168 | if not isinstance(identity[0], str) or not identity[0] or type(identity[1]) is not int:
|
| 169 | failures.append("workflow independent trial identity missing")
|
| 170 | groups.setdefault(key, []).append(json.dumps(identity, sort_keys=True))
|
| 171 | if row.get("operation") == "agent.workflow" and (row.get("agent_launched") is not True or row.get("outcome_attribution") != "agent"):
|
| 172 | failures.append("workflow outcome is not an observed agent trial")
|
| 173 | for key, identities in groups.items():
|
| 174 | if len(set(identities)) != len(identities):
|
| 175 | failures.append(f"{key[:3]}: duplicate workflow trial identities")
|
| 176 | if len(set(identities)) < min_samples:
|
| 177 | failures.append(f"{key[:3]}: workflow samples below n={min_samples}")
|
| 178 | return list(dict.fromkeys(failures))
|