Two AI includes documented themselves under names nothing else uses
This commit is contained in:
@@ -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/<id>.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';
|
||||
|
||||
@@ -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
|
||||
// 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.
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user