Repository navigation
Conversation
…ure (PRD-04 DEP-3) Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Resolve conflicts in ci.yml (keep both the DEP-6 and DEP-3 parity steps) and the core CHANGELOG ([Unreleased] above 2.6.1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
Review fixes for PRD-04 DEP-3 Part A (refs internal #537): - Collapse every line-break character, not just CR and LF. U+2028, U+2029, NEL, VT, FF and FS/GS/RS (the str.splitlines set) could still put a forged "[ID: ...]" on its own line for any model or renderer that honours them. - WASM buildDedupContext: cap is now optional (default 30) and must be a non-negative integer. As a usize, -1 silently meant "no cap" and NaN/undefined silently gave an empty block. - PyO3 build_dedup_context: cap defaults to 30. - Fixture generator strips Unicode White_Space explicitly, matching Rust str::trim (Python str.strip also strips U+001C..U+001F). Two new fixture cases cover both; the 14 existing vectors are unchanged. - Module doc states the caller contract (section sizes are the caller's job; pins crowd out the rest at cap; strip embeddings before serialising). - New tests: non-array section ValueError (PyO3), default cap, cap validation (WASM), id collapse before dedupe, 5,000-pin section stops at cap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
Stacks the write gate and DEP-3 Part B on #702 and #701. Only conflict: core CHANGELOG Unreleased/Added, both entries kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
write_gate: normalize_fact_text (NFC, case, typographic folding, whitespace, edge punctuation) and decide_write (exact match skips in every mode; cosine >= 0.85 skips in auto, confirms in explicit, stores in exact_only). PyO3 + WASM bindings, write-gate-v1 fixture from an independent Python reference, TS parity test + CI step. dedup_context (unreleased, #701): pinned lines carry "[pinned, read-only]" and the block ends with a note telling the LLM to ADD new information instead of updating a pin. Fixture regenerated in place (17 cases). Refs internal #632, #501, #537. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
Write gate (internal #632, #501): auto-extraction, totalreclaw_remember, the USER.md mirror and reconcile all call core decide_write (pure-Python fallback for older cores) against topical subgraph candidates plus a 15-minute in-memory ledger of this process's writes. The ledger covers subgraph indexing lag; forget and pin/retype rewrites keep it in step. Explicit remember of an exact copy returns already_stored; a near copy returns possible_duplicate (retry with force=true). Mirror/reconcile skip exact copies only. DEP-3 Part B: extraction sees topical top-20 (include_embeddings=True), just-written facts and the 10 newest, rendered by core build_dedup_context with pinned facts first and read-only. UPDATE without existingFactId becomes ADD. _fetch_recent_memories keeps its name (hermes/hooks.py imports it). Refs internal #632, #501, #537. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
Collaborator
Author
|
Pedro approved the possible_duplicate / already_stored responses for explicit remember (retry with force=true) on 2026-11-03. Merge is still held for the core audit. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #702 (base branch) and #701 (merged in). Merge #701 and #702 first, then retarget this PR to
main. Draft until the core audit clears.What
Every Hermes write path now asks one store-time gate before it stores a fact. It also finishes DEP-3 Part B (topical dedup context). Refs internal #632, #501, #537.
The QA near-duplicates (#632, #501) were not caused by a weak dedup context. They came from write paths with no near-duplicate check (USER.md mirror, reconcile, explicit
totalreclaw_remember) and from subgraph lag: back-to-back writes could not see each other.Write gate
write_gate.rs:normalize_fact_text(NFC, case, typographic quotes and dashes, whitespace, edge punctuation) anddecide_write(text, embedding, candidates, threshold, mode). PyO3normalize_fact_text/decide_write, WASMnormalizeFactText/decideWrite. Fixturewrite-gate-v1.jsonfrom an independent Python reference, checked in Rust, WASM and Python.include_embeddings=True), plus an in-memory ledger of this process's writes from the last 15 minutes. The ledger covers subgraph lag.forgetdrops entries, and pin/unpin/retype/set_scope move them to the new id. It never touches disk.totalreclaw_rememberreturnsalready_stored.totalreclaw_rememberreturnspossible_duplicatewith the stored text, and the agent retries withforce=trueif the new text adds or changes information;Why a near match is not a silent skip everywhere
Measured with Harrier on this machine: value changes score as high as paraphrases.
A silent cosine skip on the mirror or on explicit remember would drop corrections. The paths that have an LLM judge near matches, and the others skip only exact copies.
DEP-3 Part B
_fetch_recent_memories(state, messages, mode)keeps its name, becausehermes/hooks.pyimports it. It fetches:recallon the last 4 messages, capped at 500 chars, withinclude_embeddings=True;fetch_recent_facts, one subgraph read).embedding.is_model_available_locally()), so this fetch never starts the download.build_dedup_context, with a pure-Python fallback checked against the same fixture. Pinned facts come first.[ID: x] [pinned, read-only] text, and the block ends with a note: never UPDATE/DELETE a pin, ADD new information instead. Without it the LLM aims UPDATEs at pins and the feat(core,python): pin-aware resolution + recall pin boost (PRD-04 DEP-5, Part A) #702 guard drops the new information.dedup-context-v1.jsonregenerated in place (17 cases, unreleased).existingFactIdbecomes an ADD.PINNED_CANDIDATES_QUERY(up to 5 × 1,000 rows, and itsdecayScore_gtefilter is unverified on staging). feat(core,python): pin-aware resolution + recall pin boost (PRD-04 DEP-5, Part A) #702 puts pin state on every search result, so topical and recent pins are marked. A pin that is neither topical nor recent is not relevant to this window, and the feat(core,python): pin-aware resolution + recall pin boost (PRD-04 DEP-5, Part A) #702 guard protects it anyway.pyprojectstill says>=2.6.1. The fallbacks make the Python package work on 2.6.1, verified by running the gate tests against the PyPI 2.6.1 wheel. Raise the floor when core shipsdecide_write/build_dedup_context.Test evidence
cargo test(core): 758 + 4 passed. PyO3python::tests: 54 passed.cargo clippyis clean on the new code.check-pyfunction-parity,check-docsandcheck-phrase-safetyall OK.test_write_gate.pywere written first. Red: 15 failed. Green after the change. They cover:**kwargs(test_hermes_plugin.py).Not done
🤖 Generated with Claude Code
https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax