You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
review_service.py emits reason_code="evidence_unavailable" into ReviewUserPlaybookResult.reason_code, which is declared as a plain str in models/api_schema/domain/entities.py — not the Literal used by CandidateReviewDecision.
So the public vocabulary is effectively Literal ∪ {evidence_unavailable}, enforced nowhere and documented nowhere.
Backward-compatible in the strict sense (the field was never an enum), but:
The taxonomy itself is not MECE — unsupported_evidence is a genus and absence_inference, unsupported_causality, unseen_artifact, speculative, internal_status are all species of it. Measured consequence: six near-identical candidates asserting the same defect drew four different reject codes, plus a revise, plus an accept.
Three codes (speculative, redundant, internal_status) have no numbered check defining when they apply, so the model picks among overlapping labels with no tie-breaker.
Worth deciding whether the public field should be typed, and separately whether the codes need a strict precedence order (most specific species first, unsupported_evidence as the catch-all genus last). The prompt already does this for checks 7–8 — "Checks 7-8 only" — and that is the one place labelling is consistent.
Found during review of #426. Pre-existing.
review_service.pyemitsreason_code="evidence_unavailable"intoReviewUserPlaybookResult.reason_code, which is declared as a plainstrinmodels/api_schema/domain/entities.py— not theLiteralused byCandidateReviewDecision.So the public vocabulary is effectively
Literal ∪ {evidence_unavailable}, enforced nowhere and documented nowhere.Backward-compatible in the strict sense (the field was never an enum), but:
not_agent_decisionwith no OpenAPI signal.unsupported_evidenceis a genus andabsence_inference,unsupported_causality,unseen_artifact,speculative,internal_statusare all species of it. Measured consequence: six near-identical candidates asserting the same defect drew four different reject codes, plus a revise, plus anaccept.speculative,redundant,internal_status) have no numbered check defining when they apply, so the model picks among overlapping labels with no tie-breaker.Worth deciding whether the public field should be typed, and separately whether the codes need a strict precedence order (most specific species first,
unsupported_evidenceas the catch-all genus last). The prompt already does this for checks 7–8 — "Checks 7-8 only" — and that is the one place labelling is consistent.