Repository navigation
fix(hindsight): bind retain work to enqueue-time session identity - #64499
yingliang-zhang wants to merge 1 commit into
Conversation
|
Thanks for the focused retain-lifecycle work. The premise is confirmed on current main: The PR addresses that mechanism directly: Current main is 220 commits ahead of the PR base, but its compare contains neither touched file, so this appears mechanically salvageable. Automated hermes-sweeper review. |
1770ff3 to
dc92e2d
Compare
dc92e2d to
4abeb30
Compare
1286f49 to
fadb9b5
Compare
|
Status update after the #102117 refactor (which decomposed plugins/memory/hindsight/init.py 2440 to 1214 lines and moved machinery to {embedded,settings,setup}.py): I audited which parts of this PR the new main already carries, per sub-fix. Already on new main (absorbed):
Still missing on new main (the PR remains valuable for these):
Net: PARTIAL. I plan to port the lifecycle half (commit-time watermark, ordered retries, per-attempt deep copy, client ownership, lock serialization) onto the new decomposed structure — the identity half the refactor already independently landed. |
|
Status after auditing against current Absorbed (verified on current main):
Residual (deliberately not ported): the writer-loop lifecycle rework (claim-callback / abandoned-state machine / discard-queued-jobs on abandonment, ~the +500-line core of the original). On current main the writer's shutdown contract is drain-then-stop: the sentinel is queued and the writer completes every queued retain before exiting. The rework would change that to abandon-queued-on-shutdown — a behavior change (pending retains are dropped when the writer is wedged past the 10s join), not a bugfix for the premise this PR was reviewed on, and it trades a bounded shutdown for retain loss. If maintainers want the abandonment semantics for wedged writers, that deserves its own issue/PR scoped to the writer contract; nothing in the current code needs it to be correct. Closing as absorbed-by-main (core) with the residual documented above. Happy to reopen if the writer-contract change is wanted. Thanks for the original review @teknium1. |
|
Reopening — the 2026-09-10 closure rationale was wrong. I closed this on the belief that the enqueue-time identity freeze had been fully absorbed upstream by the #102117 refactor. What upstream I will rebase onto current |
fadb9b5 to
bf1460b
Compare
|
Ported onto current Re-scoped to what current Concrete defect on Fix: build the complete Regression test ( Verified: 79 passed in |
|
New head The rebuilt head needs a workflow approval: the three runs queued behind the fork-PR gate are
all |
_make_turn_retain_job snapshotted turns/metadata/lineage/bank_id at enqueue but still built the aretain_batch item at run time via _build_retain_kwargs, which re-reads mutable per-session attributes (_retain_tags, _observation_scopes, _retain_source, _METADATA_ATTRS). A session switch between enqueue and writer drain stamped an OLD-session retain with the NEW session's tags/scopes/metadata, producing a retain whose lineage tags contradicted its own metadata session_id. Build the whole item at enqueue time; the writer job only ships it.
bf1460b to
807eec6
Compare
|
Closing: the bundled Hindsight provider this PR patches has moved out of this repo. Thanks @yingliang-zhang for this contribution. In #119888 (merge Triage notes:
If you believe this was closed in error, comment and we will reopen. (Bulk-closed in the hindsight-move close pass.) |
_make_turn_retain_job snapshotted turns/metadata/lineage/bank_id at enqueue but still built the aretain_batch item at run time via _build_retain_kwargs, which re-reads mutable per-session attributes (_retain_tags, _observation_scopes, _retain_source). A session switch landing between enqueue and writer drain stamped an OLD-session retain with the NEW session's tags/scopes/source — a document whose lineage tags contradicted its own snapshotted metadata session_id. Build the whole item at enqueue time; the writer job only ships it. Ported from NousResearch/hermes-agent#64499 (closed in the hindsight-move close pass). Tracked in vectorize-io#4662.
Problem
_make_turn_retain_jobsnapshotted the turn payload at enqueue time but still built thearetain_batchitem at run time via_build_retain_kwargs(), which reads mutable per-session attributes:When a session switch lands between enqueue and the writer drain (easy with
retain_every_n_turns > 1or any queue backlog), an OLD-session retain ships with the NEW session's tags / observation scopes / source / metadata attrs. The snapshotted metadatasession_idthen contradicts the lineage tagsession:OLD— a self-inconsistent document in the memory bank.Fix
Build the complete item at enqueue time. The writer job only ships the frozen item:
No new surface, no new state:
_build_retain_kwargs/_retain_batchare unchanged; only the when moved.Verification
tests/plugins/memory/test_hindsight_provider.py: 79 passed (+1 new), 1 skippedTestRetainIdentityIsolation::test_queued_retain_keeps_enqueue_time_item_configgates the writer between dequeue and execution, mutates_retain_tags/_observation_scopes/_retain_sourcemid-flight, asserts the shipped item keeps enqueue-time values. Fails onmain, passes at this head.ImportErrorinlazy_deps); verified by re-running the suite on the base commit.History
Originally authored against the pre-#102117 single-file plugin. Most of that work (enqueue-time snapshot of turns/metadata/lineage/bank_id, pre-enqueue
_resolve_retain_target, flush-on-switch under OLD ids) was absorbed by the #102117 rewrite and this PR was closed on that basis — but the item-snapshot gap survived the rewrite, verified bygit cherry upstream/main. Re-scoped to exactly that residual.