Follow-up from PR #1090 review (Codex P1, comment 3768687908): when the composite check's checkQueryPii abstains (data.pii.parse_error), the review runner's detectPii returns { columns: [] }, indistinguishable from a verified-clean result, and the PII lane treats the model as clean.
Practical exposure is currently nil — an unparseable model already fails the review loudly via the validation/lint lanes, and the abstention is visible in the composite output and fails closed in the CLI/tool paths — but for the "degrade loudly" contract the lane should know the difference.
Scope: extend ReviewRunner.detectPii to return an optional abstained flag (optional field, non-breaking for mocks), set it from pii.parse_error in the dispatcher runner, and have the orchestrator PII lane mark PII checks as unverified (rather than clean) for that file.
Follow-up from PR #1090 review (Codex P1, comment 3768687908): when the composite check's
checkQueryPiiabstains (data.pii.parse_error), the review runner'sdetectPiireturns{ columns: [] }, indistinguishable from a verified-clean result, and the PII lane treats the model as clean.Practical exposure is currently nil — an unparseable model already fails the review loudly via the validation/lint lanes, and the abstention is visible in the composite output and fails closed in the CLI/tool paths — but for the "degrade loudly" contract the lane should know the difference.
Scope: extend
ReviewRunner.detectPiito return an optionalabstainedflag (optional field, non-breaking for mocks), set it frompii.parse_errorin the dispatcher runner, and have the orchestrator PII lane mark PII checks as unverified (rather than clean) for that file.