Repository navigation
fix(gates): nothing measured is not a pass #176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
edcf045
c1d1be1
a0f2251
9e7b29a
2cc66db
2d97d0e
9ab2184
55d2d08
1983d7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| ### Fixed | ||
|
|
||
| - **Nothing measured is not a pass** — gates that read an empty or all-errored result as green now exit 1 with an `incomplete` line and the counts. `repo tasks check` and `repo run` refuse an export with no task (`repo run` crashed with an IndexError on one); `repo tasks check` exits 1 when no task passed the self-check, even with `--allow-unsupported`; `repo run` exits 1 when no cell of the batch has a result, and its summary line now counts unsupported cells. `eval judge-wording` reports a condition with no scored pair as NOT MEASURED (with errored-pair counts) instead of "No rewrite moves any variant", and `--strict` exits 1 on it. `eval cross-judge` labels an arm `NOT MEASURED` when no voting measure compared a single question, and `--strict` exits 1 on that or when no arm was compared. `run --strict` exits 1 when no document was measured. Partial errors change no threshold. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -148,6 +148,11 @@ def summary(self) -> Dict[str, Any]: | |
| tests = [(v, c) for v in sorted(acc) for c in rewrites if c in acc[v] and "original" in acc[v]] | ||
| raw = [self._paired_p(v, c) for v, c in tests] | ||
| holm = dict(zip(tests, adjust_pvalues(raw, method="holm", rounded=False), strict=True)) | ||
| # A condition with no scored pair (none built, or every call errored) was | ||
| # not measured: "no rewrite moves anything" would be read off zeros, and an | ||
| # errored pair counts 0 in the sign test, so nothing is flagged either. | ||
| unmeasured = [c for c, r in self.reports.items() if not r.scored] | ||
| measured = bool(self.reports) and not unmeasured | ||
| rows = {} | ||
| for variant, by in sorted(acc.items()): | ||
| noise = [by[c] for c in floor if c in by] | ||
|
|
@@ -165,13 +170,16 @@ def summary(self) -> Dict[str, Any]: | |
| "spread": spread, | ||
| "worst_wording": worst, | ||
| "p_holm": None if p_min is None else round(p_min, 4), | ||
| "fragile": spread >= MIN_FLAGGED_SPREAD and p_min is not None and p_min < ALPHA, | ||
| "fragile": measured and spread >= MIN_FLAGGED_SPREAD and p_min is not None and p_min < ALPHA, | ||
| } | ||
| pooled = {c: r.summary()["accuracy"] for c, r in self.reports.items()} | ||
| return { | ||
| "judge": self.judge, | ||
| "conditions": list(self.reports), | ||
| "pooled_accuracy": pooled, | ||
| "n_errors": {c: len(r.errors) for c, r in self.reports.items()}, | ||
| "unmeasured_conditions": unmeasured, | ||
| "measured": measured, | ||
| "per_variant": rows, | ||
| "fragile_variants": sorted(v for v, r in rows.items() if r["fragile"]), | ||
| } | ||
|
|
@@ -200,14 +208,23 @@ def format_summary(self) -> str: | |
| lines.append( | ||
| f" {'pooled (graded)':20s} " + " ".join(f"{s['pooled_accuracy'][c]:10.2f}" for c in conds) | ||
| ) | ||
| if any(s["n_errors"].values()): | ||
| lines.append( | ||
| f" {'errored pairs':20s} " + " ".join(f"{s['n_errors'][c]:10d}" for c in conds) | ||
| ) | ||
| lines.append("") | ||
| lines.append(" * neutral variant: column is unmoved rate, not accuracy") | ||
| if not s["measured"]: | ||
| lines.append( | ||
| " NOT MEASURED — no pair scored under: " | ||
| + (", ".join(s["unmeasured_conditions"]) or "any condition") | ||
| ) | ||
| if s["fragile_variants"]: | ||
| lines.append( | ||
| " FRAGILE — a rewrite moves these on the same pairs (paired sign test, Holm): " | ||
| + ", ".join(s["fragile_variants"]) | ||
| ) | ||
| else: | ||
| elif s["measured"]: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A condition with no scored pair prints Case: 20 bases, The Suggestion: compute
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 1983d7d: |
||
| lines.append(" No rewrite moves any variant on the same pairs (paired sign test, Holm).") | ||
| return "\n".join(lines) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing pins the new
judge-wordingexit to--strict. Without the flag the new exit must not fire, and no test checks that.Mutation check: replacing
if args.strict and not summary["measured"]:withif not summary["measured"]:passestest_judge_reliability.pyandtest_judge_not_measured.pyin full (135 tests). Droppingargs.strict andfrom the FRAGILE line below passes too. Either edit makes a non-strictjudge-wordingrun exit 1 on an errored condition or a fragile variant and breaks pipelines that rely on the report-only default.This predates the PR for the FRAGILE line and for the JUDGE-DEPENDENT branch of
_strict_cross_judge_exit(if any(...)replaced byif False:also passes all 135), but the PR moved or extended both.Suggestion: in
test_judge_wording_strict_exits_1_when_a_condition_scored_no_pair, run the same argv without--strictand assert exit 0 with the NOT MEASURED line printed. Add a cross-judge--strictcase with a JUDGE-DEPENDENT arm that expects exit 1, and the same run without--strictthat expects 0.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 1983d7d: tests in
test_judge_not_measured.py. The errored-condition judge-wording run without--strictexits 0 and prints NOT MEASURED;test_judge_wording_fragile_variant_exits_1_only_with_strictpins the FRAGILE line to--strict;test_cross_judge_judge_dependent_exits_1_only_with_strictcovers the JUDGE-DEPENDENT branch (0 without, 1 with--strict).