feat(memory): add curated cross-session memory NodeTypes#1207
Merged
Conversation
Extend MemoryGraph's NodeType enum with USER_CONTEXT/FEEDBACK/ PROJECT_CONTEXT/REFERENCE, mapped 1:1 onto the harness auto-memory's own proven taxonomy (user/feedback/project/reference). These nodes represent hand-curated memory with no workflow origin and no open/resolved lifecycle - severity stays unset, status is reinterpreted as active/superseded/stale. Regression guards cover the exact pre-fix failure: reloading a saved graph containing one of these types raised `ValueError: '<value>' is not a valid NodeType` in MemoryGraph._load() -> Node.from_dict() -> NodeType(data["type"]). No schema change - existing fields are reinterpreted, not added.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
3 tasks
silversurfer562
added a commit
that referenced
this pull request
Jul 1, 2026
* fix(memory): honor status in add_finding; open friction-log spec add_finding() never read finding["status"], so every node created through the real public API silently got status="open" regardless of what the caller passed - found reviewing PR #1207's curated-memory NodeTypes (whose whole premise is that these nodes get active/superseded/stale status). Predates #1207 but falsified its design for every node written via the real API; the new regression test asserted .type but not .status, so it didn't catch it. Also opens docs/specs/memory-nodetype-friction-log/ to track real dogfood usage of the 4 new NodeTypes and log taxonomy/field friction separately from implementation bugs like this one. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(memory): PersonalMemory.query() never actually returned results query() did `for hit in pipeline.run(...)`, but the installed attune_rag's RagPipeline.run() returns a RagResult dataclass (not iterable), so every call raised TypeError, silently swallowed by a broad except and returned []. This means personal_memory_recall - the MCP tool surface - has returned zero results unconditionally since attune_rag's return type changed. Existing mocked tests couldn't catch this: their fake RagPipeline.run() returned a plain list, the same wrong shape the code assumed, so mock and code agreed with each other while both diverged from the real dependency. Fixed: query() now reads rag_result.citation.hits (CitedSource objects with .template_path/.category/.score/.excerpt), matching the pattern already used correctly in workflows/rag_code_gen.py. Updated the 3 affected mocked tests to return the real RagResult/CitedSource shape instead of a plain list, and added a new regression test that exercises the real (unmocked) attune_rag dependency end to end - verified it fails without the fix (TypeError swallowed -> empty result) and passes with it. Found via docs/specs/memory-recall-eval/ - a measure-before-build benchmark (scripts/memory_recall_eval.py) built to answer "does attune.memory's recall actually work" before investing further in the subsystem. Post-fix: hit@1/hit@3 both 100% on an 18-query ground-truth corpus (was 0%/0%). Full writeup + score-distribution caveats in the spec's decisions.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(scripts): remove unused false_positives variable in recall eval CodeQL review comment on PR #1208 flagged the dead local. --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
silversurfer562
added a commit
that referenced
this pull request
Jul 1, 2026
…find_similar spot-check (#1210) First real add_finding() captures through the 4 curated NodeTypes (PR #1207), written to ~/.attune/memory/curated_graph.json and receipt-verified from a fresh instance. Logs three friction points (repo-tracked cwd-relative default path; RELATED_TO direction defaults dropping the symmetric read; find_similar signature + threshold=0.5 muting realistic queries) plus the clean fits, and closes the session-starter's find_similar sanity-check item in the recall-eval spec (alive, not query()-dead — default tuning issue).
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.
Summary
MemoryGraph'sNodeTypeenum withUSER_CONTEXT/FEEDBACK/PROJECT_CONTEXT/REFERENCE, mapped 1:1 onto the harness auto-memory's own proven taxonomy (user/feedback/project/reference).severitystays unset,statusis reinterpreted as active/superseded/stale. No schema change.ValueError: '<value>' is not a valid NodeTypeinMemoryGraph._load() -> Node.from_dict() -> NodeType(data["type"]).This is prerequisite infrastructure for a follow-up structured one-shot evaluating whether
MemoryGraphcan hold curated cross-session memory as well as the harness's file-based auto-memory does.Test plan
pytest tests/unit/memory/test_graph.py tests/unit/memory/test_nodes_coverage_boost.py tests/memory/test_graph.py— 181 passed