Undo a manual edit by restoring what the pipeline answered, from form_answers.ai_value.
It goes through the SAME write and redraw path as updateAnswer — updateValue, then
refreshDocument — so the stored PDF is redrawn and document.isStale reports it exactly as it
does for an edit. A revert that only rewrote the row would leave the document showing the value
the user just undid.
The restored row goes back to a PIPELINE status rather than staying manual_override: reverting
means "this is the model's answer again", and leaving the human latch on would keep a retry from
ever touching the field. Which pipeline status is derived from the restored content the same way
classifyAnswer reads it — a value with content is completed, an empty one no_answer —
rather than remembered, because the original status is not recoverable and inventing completed
for an empty cell is precisely the v1 bug ("N/A" persisted as a completed answer) this feature
exists to undo. ai_value itself is untouched, so a revert is idempotent.
PRECONDITION_FAILED when the row has no ai_value: every row written before the column existed,
and every v1 run. That is a state, not a fault — canRevertToAiAnswer on the answer row tells the
client not to offer the control at all, and this is the server's own check of the same fact.
Undo a manual edit by restoring what the pipeline answered, from
form_answers.ai_value.It goes through the SAME write and redraw path as
updateAnswer—updateValue, thenrefreshDocument— so the stored PDF is redrawn anddocument.isStalereports it exactly as it does for an edit. A revert that only rewrote the row would leave the document showing the value the user just undid.The restored row goes back to a PIPELINE status rather than staying
manual_override: reverting means "this is the model's answer again", and leaving the human latch on would keep a retry from ever touching the field. Which pipeline status is derived from the restored content the same wayclassifyAnswerreads it — a value with content iscompleted, an empty oneno_answer— rather than remembered, because the original status is not recoverable and inventingcompletedfor an empty cell is precisely the v1 bug ("N/A"persisted as a completed answer) this feature exists to undo.ai_valueitself is untouched, so a revert is idempotent.PRECONDITION_FAILED when the row has no
ai_value: every row written before the column existed, and every v1 run. That is a state, not a fault —canRevertToAiAnsweron the answer row tells the client not to offer the control at all, and this is the server's own check of the same fact.