feat: reduce authoritative player mqtt state

This commit is contained in:
Media
2026-08-06 17:41:07 -05:00
parent 45083207b4
commit 8b3bdae8a0
5 changed files with 1357 additions and 0 deletions
+73
View File
@@ -1060,6 +1060,79 @@ class ControllerStore:
).fetchall()
return [self._row_to_guard(row) for row in rows]
def reconcile_active_guard(
self,
slot: int,
*,
kind: str = "player_active",
review_after: float | None = None,
details: Mapping[str, Any] | None = None,
) -> SlotGuard:
"""Replace all uncertain/pending guards with one authoritative guard."""
if slot not in SLOT_IDS:
raise ValueError("slot must be in 1..10")
with self._transaction() as connection:
now = self._now()
connection.execute(
"""
UPDATE slot_guards
SET state = 'cleared', cleared_at = ?, cleared_by = 'player',
clear_reason = 'reconciled by fresh active evidence'
WHERE state IN ('active','review_required')
""",
(now,),
)
guard_id = uuid.uuid4().hex
connection.execute(
"""
INSERT INTO slot_guards
(guard_id, slot_number, kind, state, created_at,
review_after, details_json)
VALUES (?, ?, ?, 'active', ?, ?, ?)
""",
(
guard_id,
slot,
kind,
now,
review_after,
json.dumps(details or {}, sort_keys=True),
),
)
row = connection.execute(
"SELECT * FROM slot_guards WHERE guard_id = ?", (guard_id,)
).fetchone()
assert row is not None
return self._row_to_guard(row)
def clear_playback_guards(
self,
*,
reason: str,
slot: int | None = None,
kind: str | None = None,
) -> int:
clauses = ["state IN ('active','review_required')"]
parameters: list[Any] = []
if slot is not None:
clauses.append("slot_number = ?")
parameters.append(slot)
if kind is not None:
clauses.append("kind = ?")
parameters.append(kind)
with self._transaction() as connection:
now = self._now()
result = connection.execute(
f"""
UPDATE slot_guards
SET state = 'cleared', cleared_at = ?, cleared_by = 'controller',
clear_reason = ?
WHERE {' AND '.join(clauses)}
""",
(now, reason, *parameters),
)
return result.rowcount
def mark_due_guards_for_review(self, now: float | None = None) -> list[SlotGuard]:
now = self._now() if now is None else now
with self._transaction() as connection: