Skip to content

feat: record(occurred_at=) for importing history - #13

Merged
hugo8xx merged 1 commit into
mainfrom
feat/record-occurred-at
Aug 25, 2026
Merged

feat: record(occurred_at=) for importing history#13
hugo8xx merged 1 commit into
mainfrom
feat/record-occurred-at

Conversation

@hugo8xx

@hugo8xx hugo8xx commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Client half of khwan-engine#31.

kw.record(turn, answer, occurred_at=when_it_happened)

Without it an import stamps every packet with the minute it ran. Measured on a real brain: replaying transcripts spanning 22 June → 24 August produced packets spanning twelve minutes. Retrieval then cannot tell a decision from June from one made this morning, and a recency tiebreak has nothing to work with on exactly the data most likely to hold a superseded fact.

Both clients, sync and async. Absent, the field is not sent at all — an ordinary turn carries no extra bytes and an older engine sees the body it always did.

Tests

✓ omitted when not given — no new field on an ordinary turn
✓ sent as ISO 8601 when given
✓ sent on the background path, where the body is built once

The background case matters on its own: that path builds the body once and hands it to a thread, so the timestamp has to be inside that copy rather than added afterwards.

It waits for the thread directly instead of calling flush(), which lives in #12 — so this branch stands alone and the two can merge in either order.

All existing suites pass.

0.4.0

record() grows a keyword; this is the release someone would pin to get it.

Pairs with khwan-engine #31. Without it an import stamps every packet with the
minute it ran: replaying two months of transcripts produced packets spanning
twelve minutes, so retrieval cannot tell a decision from June from one made this
morning, and a recency tiebreak has nothing to work with on exactly the data most
likely to hold a superseded fact.

Both clients. Absent, the field is not sent at all, so an ordinary turn carries no
extra bytes and an older engine sees the body it always did.

Tests cover the blocking path, the background path — where the body is built once
and handed to a thread, so the timestamp has to be in that copy — and the absence
case. The background one waits for the thread directly rather than through
flush(), which lives in another branch, so this stands alone.

0.4.0: the record signature grows a keyword, and this is the release someone
would pin to get it.
@hugo8xx
hugo8xx merged commit 7e96cb3 into main Aug 25, 2026
2 checks passed
@hugo8xx hugo8xx mentioned this pull request Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant