fix: thread_closed uses chat-clock time, not wall clock (T80.4)
T58 stamped emitted ``thread_closed`` events with ``datetime.now(timezone.utc).isoformat()``. The rest of the close pipeline (memories.chat_clock_at, scene_closed.ended_at, edge writes) uses the chat's in-world clock. Threads must agree so timeline reconstruction stays consistent under time skips and replay. Read ``chat["time"]`` (already loaded for the per-POV path) and pass it through as ``closed_at``. Falls back to UTC now only when chat_state has no clock yet — defensive; chat_created always seeds it. Adds test_thread_closed_uses_chat_clock_time.
This commit is contained in:
@@ -624,12 +624,20 @@ async def apply_scene_close_summary(
|
||||
},
|
||||
)
|
||||
elif cand.action == "close" and cand.existing_thread_id:
|
||||
# T80.4: chat-clock time, not wall clock — the rest of the
|
||||
# close pipeline (memories, edges, scene_closed payloads)
|
||||
# uses chat["time"] so threads must agree. Falls back to
|
||||
# UTC now only when the chat row has no clock yet (defensive
|
||||
# — chat_state always seeds "time" via chat_created).
|
||||
chat_clock_at = chat.get("time") or datetime.now(
|
||||
timezone.utc
|
||||
).isoformat()
|
||||
append_and_apply(
|
||||
conn,
|
||||
kind="thread_closed",
|
||||
payload={
|
||||
"thread_id": cand.existing_thread_id,
|
||||
"closed_at": datetime.now(timezone.utc).isoformat(),
|
||||
"closed_at": chat_clock_at,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user