fix(review): quick FT path enforces 3-state exclusivity + twin propagation; changelog + twin caveat
set_false_trigger now clears reviewed_real when flagging false_trigger=True
(mirrors update_event_review's exclusivity), and the quick
PATCH /db/events/{id}/false_trigger endpoint now calls
propagate_review_to_twins after the flag write, matching the sidecar PATCH
path's try/except-with-log.warning pattern. Previously the quick path could
leave both flags set and never touched twins.
Also corrects the v0.25.0 CHANGELOG bullet (exclusivity was not actually
enforced on the quick path until this commit) and adds a caveat comment on
find_twins about rare clamped/saturated-PVS false-positive twin matches.
This commit is contained in:
+28
-5
@@ -610,6 +610,16 @@ class SeismoDb:
|
||||
within ``window_seconds`` of this event's timestamp. Excludes the
|
||||
event itself. Returns [] if the event or any required field
|
||||
(serial / peak_vector_sum / timestamp) is missing.
|
||||
|
||||
Caveat: identical-PVS matching is a proxy for "same physical event
|
||||
recorded twice," not a guarantee. In the rare case where the device
|
||||
clamps/saturates PVS (clamped to sqrt(3) * geo_range), two distinct
|
||||
saturated events on the same serial within the window can share the
|
||||
same clamped PVS value and be matched as twins even though they are
|
||||
different events. This is harmless in practice — false_trigger/
|
||||
reviewed_real are derived/index columns re-derivable from the
|
||||
sidecar source of truth — but worth knowing if twin counts look
|
||||
surprising on a saturated/clamped run.
|
||||
"""
|
||||
row = self.get_event(event_id)
|
||||
if not row:
|
||||
@@ -652,12 +662,25 @@ class SeismoDb:
|
||||
return moved
|
||||
|
||||
def set_false_trigger(self, event_id: str, value: bool) -> bool:
|
||||
"""Set or clear the false_trigger flag on an event. Returns True if found."""
|
||||
"""
|
||||
Set or clear the false_trigger flag on an event. Returns True if found.
|
||||
|
||||
Mirrors the 3-state exclusivity enforced by `update_event_review`:
|
||||
setting false_trigger true also clears `reviewed_real` (a false
|
||||
trigger can't also be a confirmed-real event). Clearing false_trigger
|
||||
leaves `reviewed_real` untouched.
|
||||
"""
|
||||
with self._connect() as conn:
|
||||
cur = conn.execute(
|
||||
"UPDATE events SET false_trigger=? WHERE id=?",
|
||||
(1 if value else 0, event_id),
|
||||
)
|
||||
if value:
|
||||
cur = conn.execute(
|
||||
"UPDATE events SET false_trigger=1, reviewed_real=0 WHERE id=?",
|
||||
(event_id,),
|
||||
)
|
||||
else:
|
||||
cur = conn.execute(
|
||||
"UPDATE events SET false_trigger=0 WHERE id=?",
|
||||
(event_id,),
|
||||
)
|
||||
return cur.rowcount > 0
|
||||
|
||||
def delete_event(self, event_id: str) -> Optional[dict]:
|
||||
|
||||
Reference in New Issue
Block a user