Three bugs in the conversation/approval participant from #411. Each accepts or records something the spec says to reject. No fixture catches them.
1. The say precondition isn't validated against the conversation state. A say with a stale or empty precondition is accepted when it should be rejected as stale. The precondition is { tip: messageId | null }, where null means the conversation is empty. Validate it against the current state and reject a mismatch as stale.
The schema needs to change too. Today the precondition is optional and its tip must be a string, so a say with no precondition passes conformance and an empty conversation can't be expressed. Make the precondition required and let the tip be null. Without that, no fixture can catch a missing precondition.
2. A say or answer with no from is stored as {kind: "human"}. from must be passed through as sent, never invented. With no from, the message should be rejected, not given a made-up sender. The schema already requires from, so this is a code fix.
3. Rejection reasons are wrong. A live-acceptance rejection reports stale. An unparseable answer reports invalid_answer, which was invented. Both should report the real reason.
Guidance
Each fix includes the fixture that would have caught it, in the same commit.
Three bugs in the conversation/approval participant from #411. Each accepts or records something the spec says to reject. No fixture catches them.
1. The
sayprecondition isn't validated against the conversation state. Asaywith a stale or empty precondition is accepted when it should be rejected as stale. The precondition is{ tip: messageId | null }, wherenullmeans the conversation is empty. Validate it against the current state and reject a mismatch as stale.The schema needs to change too. Today the precondition is optional and its tip must be a string, so a
saywith no precondition passes conformance and an empty conversation can't be expressed. Make the precondition required and let the tip be null. Without that, no fixture can catch a missing precondition.2. A
sayoranswerwith nofromis stored as{kind: "human"}.frommust be passed through as sent, never invented. With nofrom, the message should be rejected, not given a made-up sender. The schema already requiresfrom, so this is a code fix.3. Rejection reasons are wrong. A live-acceptance rejection reports
stale. An unparseable answer reportsinvalid_answer, which was invented. Both should report the real reason.Guidance
Each fix includes the fixture that would have caught it, in the same commit.