Let a kept memory be taken back

Accepting put a line in every future prompt with no way out but editing the file
by hand, and a fact that is true today stops being true.
This commit is contained in:
Gmer4Lfe
2026-08-13 15:13:32 -04:00
parent 17216a354d
commit be6bb3ffc5
2 changed files with 126 additions and 15 deletions
+49 -8
View File
@@ -176,6 +176,13 @@ if (is_dir('/var/log/varaverk')) {
.vv-ai-src-tag.repair { color:#d8a15a; border-color:#4a3a1e; background:#1a1408; }
.vv-ai-src-tag.memory { color:#7d9be8; border-color:#26324a; background:#0d1220; }
/* What was decided, in a word. A decided row is greyed, which says it is settled but not which
way — and "kept" is the one that matters, because it means this text is in every prompt now. */
.vv-ai-mem-state { font-size:9px; letter-spacing:.06em; text-transform:uppercase;
border-radius:3px; padding:1px 6px; border:1px solid; flex-shrink:0; }
.vv-ai-mem-state.accepted { color:#6fcf97; border-color:#264a26; background:#0c1a0c; }
.vv-ai-mem-state.dismissed { color:#6a6a6a; border-color:#2a2a2a; background:#131313; }
/* Filter pills, loosely the shape the Monitor scripts card uses: a count you can click. All is an
explicit pill rather than "click the active one again to clear" — deselecting to get everything
back is a gesture you have to already know. A source with nothing in it still shows its pill, so
@@ -714,7 +721,15 @@ vv_ai_chat_markup('vv-ai', [
return act === 'fix' ? 'Confirm write'
: act === 'dismiss' ? 'Confirm — permanent' : null;
}
return act === 'accept' ? 'Confirm keep' : null;
// Keeping is armed because it is the only route by which model-written text reaches a future
// prompt. Forgetting is armed because it drops the record that stops the same line being
// proposed again, and there is no undo for a provenance you no longer have.
//
// Retract and dismiss are not: both only ever remove something, and both are one click from
// being put back.
if (act === 'accept' || act === 'keep') return 'Confirm keep';
if (act === 'forget') return 'Confirm forget';
return null;
}
let fndArmTimer = null;
@@ -875,22 +890,42 @@ vv_ai_chat_markup('vv-ai', [
function qMemoryHtml(row) {
const r = row.raw;
const meta = [r.id, ago(r.created), r.profile || null,
row.closed ? r.state + (r.auto ? ' (auto)' : '') : null].filter(Boolean).join(' · ');
const meta = [r.id, ago(r.created), r.profile || null].filter(Boolean).join(' · ');
// Said as a word rather than left to be read off the greying, because "kept" is the state
// that matters — it means this text is in every prompt right now.
const stateWord = r.state === 'accepted' ? (r.auto ? 'kept automatically' : 'kept')
: r.state === 'dismissed' ? 'dismissed' : '';
const badge = row.closed
? `<span class="vv-ai-mem-state ${esc(r.state)}">${esc(stateWord)}</span>` : '';
// The question is the provenance. A line read three weeks from now is judged by what was
// being asked when the model decided it was worth keeping.
const asked = r.asked ? `<div class="vv-ai-fnd-n">asked: ${esc(r.asked)}</div>` : '';
// No severity class: a proposal is not a fault, and colouring it like one would make a card
// of ordinary suggestions read as a card of problems.
const acts = row.closed ? '' :
`<button class="vv-ai-btn" data-mem-act="accept" data-id="${esc(r.id)}" `
+ `title="Add this to learned memory">Keep</button>`
+ `<button class="vv-ai-btn ghost" data-mem-act="dismiss" data-id="${esc(r.id)}" `
+ `title="Never propose this again">Dismiss</button>`;
//
// A decision is not final. An accepted line joins every future prompt and nothing expires it,
// so a fact that is true today — HOST2 is offline — needs a way back out on the day it stops
// being true. Retract is that way; Keep is the same door in the other direction.
const B = (act, cls, label, tip) =>
`<button class="vv-ai-btn${cls}" data-mem-act="${act}" data-id="${esc(r.id)}" `
+ `title="${esc(tip)}">${esc(label)}</button>`;
let acts;
if (!row.closed) {
acts = B('accept', '', 'Keep', 'Add this to learned memory')
+ B('dismiss', ' ghost', 'Dismiss', 'Do not keep it, and do not propose it again');
} else if (r.state === 'accepted') {
acts = B('retract', '', 'Retract', 'Take this back out of every future prompt')
+ B('forget', ' ghost', 'Forget', 'Remove it and stop tracking it — it may be proposed again');
} else {
acts = B('keep', '', 'Keep', 'Changed your mind — add it to learned memory after all')
+ B('forget', ' ghost', 'Forget', 'Stop tracking it — it may be proposed again');
}
return `<div class="vv-ai-fnd${row.closed ? ' closed' : ''}">
<div class="vv-ai-fnd-h">
<span class="vv-ai-src-tag memory">memory</span>
${badge}
<span class="vv-ai-fnd-m">${esc(meta)}</span>
</div>
<pre class="vv-ai-fnd-e">${esc(r.text)}</pre>
@@ -973,6 +1008,12 @@ vv_ai_chat_markup('vv-ai', [
return 'Stays closed even when it is seen again. '
+ 'Use “I know” to be told if it changes. Click again to confirm.';
}
if (act === 'forget') {
return 'Drops the record, so nothing stops this being proposed again — dismissed rows are '
+ 'what suppress a repeat.'
+ (row.raw.state === 'accepted' ? ' It is removed from memory first.' : '')
+ ' Click again to confirm.';
}
return 'This text joins every future prompt. Click again to confirm.';
}