Erase owner metadata; session-only erasure retains retry tombstones.
Source and destination share the complete owner, so matching the receipt
owner removes only requests whose entire identity is covered by this erase.
Source code in src/symfonic/memory/backends/postgres_conversation_fork.py
| async def forget_receipts(
conn: Any, scope: MemoryScope, native_child_prefix: str | None = None,
) -> None:
"""Erase owner metadata; session-only erasure retains retry tombstones.
Source and destination share the complete owner, so matching the receipt
owner removes only requests whose entire identity is covered by this erase.
"""
if scope.identity_version == 1 and native_child_prefix is None:
raise MemoryContractError("native receipt erase requires the canonical child prefix")
prefix = native_child_prefix if scope.identity_version == 1 else scope.path + "/"
candidates = await conn.fetch(
'SELECT DISTINCT owner_path FROM native_conversation_forks '
'WHERE owner_path COLLATE "C" = $1 '
'OR left(owner_path, length($2)) COLLATE "C" = $2', scope.path, prefix,
)
paths = []
for row in candidates:
try:
if scope.covers(scope_from_path(row["owner_path"])):
paths.append(row["owner_path"])
except MemoryContractError:
continue
if paths:
await conn.execute("DELETE FROM native_conversation_forks "
"WHERE owner_path = ANY($1::text[])", paths)
destinations = await conn.fetch(
'SELECT DISTINCT destination_path FROM native_conversation_forks '
'WHERE destination_path COLLATE "C" = $1 '
'OR left(destination_path, length($2)) COLLATE "C" = $2', scope.path, prefix,
)
paths = []
for row in destinations:
try:
if scope.covers(scope_from_path(row["destination_path"])):
paths.append(row["destination_path"])
except MemoryContractError:
continue
if paths:
await conn.execute("UPDATE native_conversation_forks SET destination_forgotten=TRUE "
"WHERE destination_path = ANY($1::text[])", paths)
|