feat: feedback system, adaptive retrieval, governance audit trail, API hardening, and comprehensive e2e tests#65
Merged
XuPeng-SH merged 17 commits intomatrixorigin:mainfrom Mar 20, 2026
Conversation
Feedback weight closed-loop: - search_hybrid_from_scored() accepts feedback_weight parameter - retrieve_inner() loads per-user params from mem_user_retrieval_params - Fulltext fallback path also uses per-user feedback_weight - Hardcoded 0.1 replaced at all 3 scoring call sites - .max().min() → .clamp() (clippy) Observability: - GET /metrics — Prometheus text exposition format memoria_memories_total, memoria_users_total, memoria_feedback_total, memoria_graph_nodes_total, memoria_graph_edges_total, memoria_snapshots_total, memoria_branches_total, memoria_async_tasks, memoria_governance_last_run_timestamp, memoria_info Config visibility: - GET /admin/config — runtime config with redacted DB password Tests: - test_tuning_affects_scoring rewritten to verify scoring math directly (avoids MatrixOne fulltext index flakiness on consecutive retrieves) - Tool count tests updated: 15 → 18
Two processes with identical MEMORIA_INSTANCE_ID would previously share the same holder_id, causing the re-entrant lock path to let both processes acquire the governance lock simultaneously. Fix: Config::from_env() appends the OS process ID to instance_id: MEMORIA_INSTANCE_ID=pod-0 → holder_id = 'pod-0-12345' This ensures each process has a unique holder_id regardless of the configured base name, while preserving re-entrant behavior within a single process. Tests: - test_governance_daily_tunes_params_in_db: verifies DefaultGovernanceStrategy Daily task actually writes updated feedback_weight to mem_user_retrieval_params - test_duplicate_instance_id_lock_is_exclusive: verifies PID suffix prevents two processes with same base instance_id from both acquiring the lock
tune_params() has three branches: - useful_ratio > 0.7 → weight * 1.1 (was tested) - negative_ratio > 0.5 → weight * 0.9 (NEW) - neutral zone → weight unchanged (NEW) - weight clamped [0.05, 0.2] (NEW) Added test_tune_params_negative_feedback_decreases_weight covering all four cases via in-memory MockStore (no DB required).
Logging: - Add TraceLayer: every request logs method+path+status+latency_ms (error level for 5xx, warn for 4xx, debug for 2xx/3xx) - Auth failures now logged with warn! + token prefix (first 8 chars) Input validation (DoS prevention): - content: reject empty or >32 KiB - top_k: clamp to [1, 100] on retrieve and search - batch_store: reject >100 items; per-item content size check Prometheus metrics (new counters): - memoria_auth_failures_total: incremented on every 401/403 - memoria_sensitivity_blocks_total: incremented when sensitivity filter blocks a store request
Merged plan-memory-integration into goal-driven-evolution.md: - Query memory before starting multi-step tasks (GOAL, LESSON, ANTIPATTERN) - Register goals for multi-session work - Track steps during execution (working type) - Capture user feedback immediately (procedural type) - Iteration review and cleanup workflow - Changed inclusion from agent_requested to always Applies to all AI tools: Kiro plan panel, Cursor Composer, Claude multi-step.
Merged plan-memory-integration into goal-driven-evolution.md: - Query memory before starting multi-step tasks (GOAL, LESSON, ANTIPATTERN) - Changed inclusion from agent_requested to always Preserved all original content: - 📋 PLAN structured storage with steps and risks - 👍 FEEDBACK for positive experiences - 🔄 RETRO with Completed [M/N], Key insight, Next improvements - Bootstrap queries RETRO for context restoration - Branch merge complete workflow (diff, checkout, merge, delete) - Goal completion records Iterations count and Final approach Added: - When Goal is Abandoned section - Don't create goals for quick fixes rule Applies to all AI tools: Kiro plan panel, Cursor Composer, Claude multi-step.
- README: added memory_feedback to Core Tools table
- API Reference skill: added Feedback & Adaptive Retrieval section
- POST /v1/memories/{id}/feedback
- GET /v1/feedback/stats
- GET /v1/feedback/by-tier
- POST /v1/retrieval-params/tune
- GET /v1/retrieval-params
- Steering rules (kiro/cursor/claude): added memory_feedback to Read tools
with usage guidance (when to call, signal types)
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.
What type of PR is this?
Which issue(s) this PR fixes
Fixes #
What this PR does / why we need it
1. Feedback & Adaptive Retrieval System
mem_retrieval_feedbacktable for explicit relevance signals (useful/irrelevant/outdated/wrong)mem_user_retrieval_paramstable for per-user adaptive scoring parametersrecord_feedback()validates signals, verifies memory ownership, updates denormalized counterssearch_hybrid_from_scored()applies feedback adjustment:(1 + fw * (useful - 0.5*negative)).clamp(0.5, 2.0)DefaultScoringPluginauto-tunes feedback_weight based on signal ratios (≥10 feedback threshold)POST /v1/memories/:id/feedback,GET /v1/feedback/stats,GET /v1/feedback/by-tier,GET/PUT /v1/retrieval-params,POST /v1/retrieval-params/tune2. Governance Audit Trail Enhancement
{"quarantined": N},{"cleaned_stale": N}, etc.mem_edit_logredesigned:target_ids JSON→memory_id VARCHAR(64)+payload JSON, no PK,CLUSTER BY, UUID v7 for edit_id3. API Error Handling Improvements
MemoriaError::Validationvariant for input validation errorsapi_err_typed()function maps error variants to proper HTTP status codes:NotFound→ 404Validation/InvalidMemoryType/InvalidTrustTier→ 422Blocked→ 403record_feedbackandstore_memoryhandlers4. Prometheus Metrics & Admin Config
GET /metricsendpoint: Prometheus text exposition format with memoria_memories_total, memoria_users_total, memoria_auth_failures_total, etc.GET /admin/config(master-key-only): runtime config view with redacted DB password5. MCP Tool Surface Reduction
list()but still callable via REST/direct invocation:memory_rebuild_index,memory_get_retrieval_params,memory_tune_params,memory_extract_entities,memory_link_entities6. Comprehensive E2E Test Coverage
test_api_feedback_invalid_signal(422 for invalid signal),test_api_tune_retrieval_params(COALESCE fix for empty feedback)/metrics,/v1/snapshots/:name/rollback,/v1/entities,/admin/config(with master-key auth)7. Documentation & Templates Sync
Bug Fixes
get_feedback_stats()NULL handling with COALESCE for empty feedback tablesupsert_entity(): INSERT-first, catch "Duplicate entry" errorbatch_upsert_memory_entity_links()to use multi-row INSERT with ON DUPLICATE KEY UPDATE