From e69aa2be0414fdb4de3ee6888705c7fb9e3f88a3 Mon Sep 17 00:00:00 2001 From: matevip Date: Tue, 21 Apr 2026 17:34:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(memory):=20P2=20review=20fixes=20=E2=80=94?= =?UTF-8?q?=20API=20boundaries=20+=20identity=20+=20experimental=20flag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mate/memory/controller/DreamController.java | 15 +++++++++++++-- .../fact/contradiction/ContradictionDetector.java | 7 ++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/mateclaw-server/src/main/java/vip/mate/memory/controller/DreamController.java b/mateclaw-server/src/main/java/vip/mate/memory/controller/DreamController.java index d55cbd86..4a6aec6a 100644 --- a/mateclaw-server/src/main/java/vip/mate/memory/controller/DreamController.java +++ b/mateclaw-server/src/main/java/vip/mate/memory/controller/DreamController.java @@ -129,6 +129,17 @@ public class DreamController { @PathVariable Long reportId, @PathVariable String key, @RequestBody Map body) { + // P2-5: Validate reportId belongs to this agent (0 = direct edit, skip validation) + if (reportId != 0L) { + DreamReportEntity report = dreamReportMapper.selectOne( + new LambdaQueryWrapper() + .eq(DreamReportEntity::getId, reportId) + .eq(DreamReportEntity::getAgentId, agentId) + .eq(DreamReportEntity::getDeleted, 0)); + if (report == null) { + return R.fail("Report not found or does not belong to this agent"); + } + } String newContent = body.get("content"); if (newContent == null || newContent.isBlank()) { return R.fail("content is required"); @@ -144,8 +155,8 @@ public class DreamController { if (principal instanceof vip.mate.auth.model.UserEntity user) { return user.getId(); } - // Fallback: use abs(hashCode) to avoid negative IDs, add offset to avoid collision with real IDs - return Math.abs((long) auth.getName().hashCode()) + 1_000_000_000L; + // No stable user ID available โ€” refuse rather than fabricate + return null; } catch (Exception e) { return null; } diff --git a/mateclaw-server/src/main/java/vip/mate/memory/fact/contradiction/ContradictionDetector.java b/mateclaw-server/src/main/java/vip/mate/memory/fact/contradiction/ContradictionDetector.java index 74532484..9fc87dcb 100644 --- a/mateclaw-server/src/main/java/vip/mate/memory/fact/contradiction/ContradictionDetector.java +++ b/mateclaw-server/src/main/java/vip/mate/memory/fact/contradiction/ContradictionDetector.java @@ -21,9 +21,10 @@ import java.util.Set; * Called as a synchronous step at the end of MemoryEmergenceService.consolidate * (rfc-038 ยง3.7, decision D11 โ€” NOT an event listener). * - *

Phase 3 L1: simple string-overlap detection between promoted entries - * and existing facts with the same subject but different object values. - * Full LLM batch judgment deferred to Phase 3 L4+. + *

EXPERIMENTAL โ€” Phase 3 L1 uses simple string-overlap detection + * (same subject, different object). False positives are expected. + * Gated behind {@code mate.memory.fact.contradiction-check-enabled=false} (default off). + * Full LLM batch judgment (using contradiction-batch.txt prompt) deferred to Phase 3 L4+. * * @author MateClaw Team */