Stop one unknown action from discarding a whole commit #640

Merged ngerakines.me
targeting main
Merged opened by and assigned to ngerakines.me
targeting main

com.atproto.sync.subscribeRepos declares #repoOp.action with knownValues, not enum: create, update and delete are the strings defined today, not the only ones a conforming server may send. RepoOpAction modelled them as a closed serde enum, so an action added tomorrow fails the op, which fails ops, which fails CommitEnvelope -- one unrecognised word discards an entire firehose commit along with every op the build did understand. The failure is silent in the worst way: the consumer sees a decode error, not a commit it half-read.

Other(String) keeps the string. Serialize and Deserialize are hand-rolled over &str rather than derived, so the three known actions still cost no allocation and encode byte-for-byte as rename_all = "lowercase" did -- the change is invisible to existing consumers and to every commit CID already stored. Only Other owns its string.

Copy goes, since Other carries a String. The ripple is smaller than that usually implies: none of the existing matches bind by value, so none of them moves out of a borrow, and atproto-pds's two writer sites compile unchanged. Their _ => arm reports the op's own cid, which is right for any action.

verify_op_inclusion skips an op it cannot interpret and emits no verdict. verified: false would have been the wrong answer -- it says the commit lied about an op nobody read, and "not proven" is not "disproven". The check sits ahead of the MST lookup rather than in the match, because mst.get can fail and an op being deliberately ignored must not be able to fail the whole verification on an unrelated storage error.

applyWrites in atproto-pds needed a third site the writer sites did not: its match was exhaustive. Other is unreachable there -- those ops come from this server's own ops_with_prev_cids -- but the results array is positional, so dropping an entry misaligns every result after it, and the response union is genuinely closed with no member for "something else". It logs the impossibility and reports the shape the op's cid implies.

The test that matters decodes a #commit frame whose ops holds an unknown action between two known ones and asserts all three survive; the known pair is what the old behaviour threw away. It asserts the retained string too, which is the assertion #[serde(other)] would fail -- a unit variant can report that something was skipped but never what.

This pull request has no versions submitted yet.