corpus: align determinability key with the schema column

The truth files used `determinableFromResponseDocument`; the schema column
and gateEvaluableFromResponse() use `determinableFromResponse`. A silent
name drift means the flag reads as its default (true), and R-B6C — "two bid
copies submitted", which no response document can ever establish — starts
failing bidders on a packaging detail.

Renamed in rfp.truth.json and validate-responses.py, and added the mirror
check to validate-truth.py so the drift cannot recur unnoticed:

  gates 13, evaluable from the response 12, excluded 1
    excluded: R-B6C  Two bid copies submitted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Croissant Le Doux
2026-08-03 19:52:32 -04:00
parent 126e94a14b
commit a36956b1e1
3 changed files with 18 additions and 2 deletions

View File

@@ -77,6 +77,22 @@ for cid in sec:
if cid not in crit: errs.append(f"bindingMechanism section -> unknown criterion {cid}")
gates = [r for r in t['requirements'] if r['kind'] == 'mandatory_gate']
# Mirrors gateEvaluableFromResponse() in src/scoring/routing.ts. The key read
# here is the SCHEMA COLUMN NAME on purpose — the two names drifted once, and a
# silent drift means the flag reads as its default and a bidder is disqualified
# over something no document could have proven.
evaluable = [r for r in gates if r.get('determinableFromResponse', True)]
excluded = [r for r in gates if not r.get('determinableFromResponse', True)]
print(f" ok gates {len(gates)}, evaluable from the response {len(evaluable)}, "
f"excluded {len(excluded)}")
for r in excluded:
print(f" excluded: {r['id']:14} {r['text'][:50]}")
for r in t['requirements']:
if r.get('determinableFromResponse') is False and r['kind'] != 'mandatory_gate':
warns.append(f"{r['id']} is not determinable but is not a gate — the flag "
f"only changes gate evaluation, so this has no effect")
kinds = {}
for r in t['requirements']: kinds[r['kind']] = kinds.get(r['kind'], 0) + 1
print(f"\n requirements {len(t['requirements'])} criteria {len(t['criteria'])} knownMisses {len(t['knownMisses'])}")