feat(memory-v2): auto-accept candidate memories in active and canary modes

Let Personal Memory candidates pass policy gates without per-user manual review, while keeping shadow mode for explicit human approval.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-13 14:16:57 +08:00
parent 7f7aced751
commit b33c943b69
4 changed files with 147 additions and 13 deletions
+10 -4
View File
@@ -60,13 +60,16 @@ export function createPersonalMemoryCandidateStore(pool, { table = TABLE, now =
const quoted = `\`${table}\``;
return {
async saveCandidate(candidate) {
async saveCandidate(candidate, { autoAccept = false, reviewedBy = 'system:auto-review' } = {}) {
const updatedAt = now();
const status = autoAccept ? 'accepted' : 'candidate';
const reviewedAt = autoAccept ? updatedAt : null;
const reviewer = autoAccept ? String(reviewedBy || 'system:auto-review') : null;
const [result] = await pool.query(
`INSERT IGNORE INTO ${quoted}
(id, user_id, session_id, memory_type, content, importance, confidence, status,
policy_reason, evidence_json, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, 'candidate', ?, ?, ?, ?)`,
policy_reason, evidence_json, reviewed_by, reviewed_at, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
candidate.id,
candidate.userId,
@@ -75,13 +78,16 @@ export function createPersonalMemoryCandidateStore(pool, { table = TABLE, now =
candidate.content,
candidate.importance,
candidate.confidence,
status,
candidate.policyReason,
JSON.stringify(candidate.evidence ?? {}),
reviewer,
reviewedAt,
candidate.createdAt,
updatedAt,
],
);
return { inserted: Number(result?.affectedRows ?? 0) > 0 };
return { inserted: Number(result?.affectedRows ?? 0) > 0, status };
},
async listCandidates({ status = 'candidate', userId = null, limit = 50, offset = 0 } = {}) {