fix(advice): the pre-token guard, and a stripper that cannot empty real advice
Two findings from the fifth review.
The pre-token fallback re-opened the hole
-----------------------------------------
A reading that has never been edited has no token. The guard fell back
to the gravity check for those, and a comment-only correction leaves the
gravity unchanged - so a late thread's write matched and overwrote the
fresh advice, for exactly the 47 existing readings.
Reproduced live before the fix:
pre-token reading token: None -> stale thread carries ""
fresh write modified: 1
stale write modified: 1 <<< stale advice overwrote the fresh one
final advice: 'STALE ADVICE'
The guard now matches on the ABSENCE of a token, which still tells the
generations apart: an edit writes a token, so a stale thread's "" stops
matching the moment the reading is corrected.
fresh write modified: 1 (must be 1)
stale write modified: 0 (must be 0)
The stripper could empty real advice
------------------------------------
"Actually the drop is fine.\\n\\nWait a couple of days and check again."
is advice, and judging it paragraph by paragraph emptied it - so the
brewer saw nothing at all, with no failure note.
The test is no longer a marker list, which real advice often does not
contain. A reply is all-working when it is LONG and has no instruction
in it: the model's working runs to thousands of characters, while the
advice is two to five sentences.
short reply with no marker -> kept
long reply, no instruction -> dropped
long reply with advice -> advice kept
single-paragraph working -> dropped
Also: the log message named the gravity, but the guard is the token.
182 tests (up from 178).
This commit is contained in:
@@ -267,14 +267,20 @@ class BeerRepository:
|
||||
# The editing token is the PRIMARY guard: it changes on every
|
||||
# edit, so it catches a stale generation whatever else
|
||||
# changed - the gravity, the comment, or nothing.
|
||||
#
|
||||
# An EMPTY token is not a usable guard: it means the reading
|
||||
# predates the token, so there is no token to match.
|
||||
# Querying on it would match nothing, and the advice would
|
||||
# never be written for the existing readings.
|
||||
query["advice_token"] = str(expected_token)
|
||||
elif expected_token == "":
|
||||
# The reading has NEVER been edited, so it has no token at
|
||||
# all. Match on the ABSENCE of one, which still tells the
|
||||
# generations apart: an edit writes a token, so a stale
|
||||
# thread's "" stops matching the moment the reading is
|
||||
# corrected.
|
||||
#
|
||||
# Falling back to the gravity here would re-open the hole
|
||||
# this guard exists to close - a comment-only correction
|
||||
# leaves the gravity unchanged.
|
||||
query["advice_token"] = {"$exists": False}
|
||||
elif expected_sg is not None:
|
||||
# No token - a direct call with a gravity to check against.
|
||||
# A direct call with a gravity to check against.
|
||||
query["sg"] = str(expected_sg)
|
||||
|
||||
# `$in` matches either form. A plain list would be an exact
|
||||
|
||||
Reference in New Issue
Block a user