From 1be259b66d0434d0b0fcdc15207dd450a26f99c8 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Tue, 25 Aug 2026 16:31:43 -0400 Subject: [PATCH] Two AI includes documented themselves under names nothing else uses --- Plugin/unraid/include/ai_memory_learn.php | 62 ++++++++++++------- Plugin/unraid/include/ai_profiles.php | 72 ++++++++++++----------- 2 files changed, 80 insertions(+), 54 deletions(-) diff --git a/Plugin/unraid/include/ai_memory_learn.php b/Plugin/unraid/include/ai_memory_learn.php index 5b2e66e..dc2e316 100644 --- a/Plugin/unraid/include/ai_memory_learn.php +++ b/Plugin/unraid/include/ai_memory_learn.php @@ -8,31 +8,53 @@ // the prompt on its own. A proposal is filed; the operator accepts or dismisses it; accepted // text lands in the learned memory slot, which the prompt explicitly ranks BELOW retrieval. // -// WHY IT IS A PROPOSAL AND NOT A WRITE -// Memory is injected into every future prompt. A model that writes its own memory writes its -// own mistakes, and then reads them back as established fact — growing more confident on each -// turn while the actual source code says otherwise. The cost of a bad proposal has to be one -// dismissal, not a permanently poisoned prompt. This is the same two-gate shape the repair -// system uses, for the same reason: whether something should be remembered is intent, and a -// model cannot prove intent. +// DESIGN PRINCIPLES +// It is a proposal, never a write. +// Memory is injected into every future prompt. A model that writes its own memory writes +// its own mistakes, and then reads them back as established fact — growing more confident +// on each turn while the actual source code says otherwise. The cost of a bad proposal has +// to be one dismissal, not a permanently poisoned prompt. This is the same two-gate shape +// the repair system uses, for the same reason: whether something should be remembered is +// intent, and a model cannot prove intent. // -// WHY DEDUP IS NOT THE MODEL'S JOB -// "Do I already know this" is a semantic comparison, and a 14B at IQ4_XS is confidently wrong -// at it often enough to matter — with every miss costing budget permanently. So dedup here is -// deterministic: normalise, then reject on exact match or containment in either direction -// against assisted memory, learned memory, and everything previously dismissed. It will let -// through a reworded duplicate; it will never silently drop something new, and that is the -// right way round for a store the operator reviews anyway. +// Dedup is deterministic, not the model's job. +// "Do I already know this" is a semantic comparison, and a 14B at IQ4_XS is confidently +// wrong at it often enough to matter — with every miss costing budget permanently. So +// dedup here is deterministic: normalise, then reject on exact match or containment in +// either direction against assisted memory, learned memory, and everything previously +// dismissed. It will let through a reworded duplicate; it will never silently drop +// something new, and that is the right way round for a store the operator reviews anyway. // -// GATES -// AI_MEMORY_LEARN_ENABLED false — nothing is proposed, and the prompt gains nothing -// AI_MEMORY_LEARN_AUTO_ACCEPT false — accepted writes happen only when the operator says so -// The second cannot outrank the first: auto-accept with proposing off does nothing at all. +// OPERATIONAL SAFEGUARDS +// Two gates, and the second cannot outrank the first. +// AI_MEMORY_LEARN_ENABLED off means nothing is proposed at all, so auto-accept with +// proposing off does nothing. Neither defaults to on. +// +// Dismissed rows are kept, not deleted. +// They are the only thing that stops the same suggestion arriving again every night. A +// store that forgot its refusals would re-propose what the operator has already judged. +// +// Nothing here reaches the prompt directly. Accepted text lands in the learned memory slot, +// which the prompt ranks BELOW retrieval — so even an accepted mistake cannot outrank the +// source code it contradicts. +// +// EXPORTS +// Gates vv_ai_mem_learn_enabled(), vv_ai_mem_learn_auto() +// Dedup vv_ai_mem_norm(), vv_ai_mem_known(), vv_ai_mem_is_dup(), vv_ai_mem_is_ui_fact() +// Store vv_ai_mem_dir(), vv_ai_mem_propose(), vv_ai_mem_list(), vv_ai_mem_remove(), +// vv_ai_mem_append(), vv_ai_mem_write_row() +// Operator vv_ai_mem_action() +// — accept or dismiss one proposal. The only entry that changes what a future +// prompt will contain. +// +// CONFIGURATION +// master.conf +// AI_MEMORY_LEARN_ENABLED propose at all. Default false. +// AI_MEMORY_LEARN_AUTO_ACCEPT write accepted text without asking. Default false. // // STORE // data/ai/mem_proposals/.json — one file per proposal, mirroring the findings store. -// States: open | accepted | dismissed. Dismissed rows are KEPT, because they are what stops -// the same suggestion arriving again every night. +// States: open | accepted | dismissed. // ═══════════════════════════════════════════════════════════════════════════════════════════════ require_once __DIR__ . '/ai.php'; diff --git a/Plugin/unraid/include/ai_profiles.php b/Plugin/unraid/include/ai_profiles.php index 00ec06c..ae7d26c 100644 --- a/Plugin/unraid/include/ai_profiles.php +++ b/Plugin/unraid/include/ai_profiles.php @@ -5,47 +5,51 @@ // shared chat include and every page that renders it — reads it from here instead of // restating it. // -// WHY THIS EXISTS -// A profile used to be defined in five places: history depth in api/ai.php, capabilities in -// include/ai.php, label/hint/depth again in the chat's JavaScript, a prompt branch in the -// worker, and a label map in pages/scheduler.php. They had already drifted — the JavaScript -// knew three profiles where PHP knew four, so the shared chat could not offer troubleshoot at -// all and the Scheduler dock hand-rolled its own labels to compensate. The include carried a -// comment telling the next person not to let the two tables diverge, which is a comment doing -// a data structure's job. +// DESIGN PRINCIPLES +// One definition, not five. +// A profile used to be defined in five places: history depth in api/ai.php, capabilities +// in include/ai.php, label/hint/depth again in the chat's JavaScript, a prompt branch in +// the worker, and a label map in pages/scheduler.php. They had already drifted — the +// JavaScript knew three profiles where PHP knew four, so the shared chat could not offer +// troubleshoot at all and the Scheduler dock hand-rolled its own labels to compensate. The +// include carried a comment telling the next person not to let the two tables diverge, +// which is a comment doing a data structure's job. // -// WHAT LIVES HERE, AND WHAT DELIBERATELY DOES NOT -// Here: anything more than one file needs to agree on — the set of profiles, their labels and -// hints, history depth, capabilities, and whether a profile is offered as a button. +// What lives here is whatever more than one file must agree on. +// The set of profiles, their labels and hints, history depth, capabilities, and whether a +// profile is offered as a button. // -// Not here: the system prompts. They are long, delicate, and have exactly one consumer, so -// moving them would be churn against the most sensitive text in the subsystem for no reduction -// in duplication. Tools/ai_chat_worker.php still owns them; it just keys off ids validated -// here rather than an if-chain that invents its own vocabulary. +// Not the system prompts. They are long, delicate, and have exactly one consumer, so +// moving them would be churn against the most sensitive text in the subsystem for no +// reduction in duplication. Tools/ai_chat_worker.php still owns them; it just keys off ids +// validated here rather than an if-chain that invents its own vocabulary. // -// CAPABILITIES ARE PER PROFILE, NOT PER CAPABILITY -// The old table was inverted — capability => [profiles] — which reads well when adding a -// capability and badly when answering the question actually asked at runtime, which is always -// "what can this profile do". Same content, turned the right way round. +// Capabilities are stored per profile, not per capability. +// The old table was inverted — capability => [profiles] — which reads well when adding a +// capability and badly when answering the question actually asked at runtime, which is +// always "what can this profile do". Same content, turned the right way round. // -// A profile is a contract plus a set of inputs, and the inputs are the half that has to be -// enforced rather than requested. The caps list is that half. +// A profile is a contract plus a set of inputs, and the inputs are the half that has to be +// enforced rather than requested. The caps list is that half. // -// It exists because the alternative already failed. The same permissions used to live as a -// dozen `$profile === 'varaverk' || $profile === 'troubleshoot'` conditions spread across the -// worker, and answering "may chat ever be shown a log?" meant reading all of them. It could — -// a gate added for run-outcome questions granted it by omission, and the chat profile, whose -// entire value is that it has NOT been shown this installation, was one phrasing away from -// being handed a health sweep and 120 lines of log. Nothing about that was visible at the -// point of the mistake. Here it would have been one missing word on one line. +// OPERATIONAL SAFEGUARDS +// The capability list is the grant, and it is enforced in one place. +// The same permissions used to live as a dozen `$profile === 'varaverk' || $profile === +// 'troubleshoot'` conditions spread across the worker, and answering "may chat ever be +// shown a log?" meant reading all of them. It could — a gate added for run-outcome +// questions granted it by omission, and the chat profile, whose entire value is that it +// has NOT been shown this installation, was one phrasing away from being handed a health +// sweep and 120 lines of log. Nothing about that was visible at the point of the mistake. +// Here it would have been one missing word on one line. // -// A capability is permission, not need. varaverk holds 'health' but only attaches it when the -// question looks diagnostic; troubleshoot attaches it always. The gates decide whether an -// input is warranted, this decides whether it is allowed, and a gate can never widen the grant. +// A capability is permission, not need. +// varaverk holds 'health' but only attaches it when the question looks diagnostic; +// troubleshoot attaches it always. The gates decide whether an input is warranted, this +// decides whether it is allowed, and a gate can never widen the grant. // -// chat holding an empty capability list is a guarantee, not an oversight. Anything added to it -// stops being general chat and becomes an assistant that sometimes lies about this -// installation. +// chat holding an empty capability list is a guarantee, not an oversight. +// Anything added to it stops being general chat and becomes an assistant that sometimes +// lies about this installation. // // EXPORTS // vv_ai_profiles() the whole table