Custom Scripts run as root on a schedule, so the expensive mistake is not
tangled logic — it is a simple script aimed one directory too high. The prompt
now asks for the dry-run form and an explicit line on what gets destroyed, and
a scan of the generated code blocks raises a banner regardless of whether the
model bothered to warn. Scans fenced code only, so prose mentioning rm does not
trip it.
Given its own broken script and the real error, it produced the correct fix but
explained --no-overwrite away as 'introduced in a later version of rsync'. No
rsync version has ever had that flag, and the operator is on current 3.4.4 — so
the repair was right and the diagnosis was a second fabrication that would send
someone hunting a nonexistent upgrade.
The pattern required three underscore-separated segments, so RSYNC_ENABLED and
AI_ENABLED slipped through — exactly the names most likely to be asked about.
Also dropped the case-insensitive flag, which made the SCREAMING_CASE branch
match ordinary lowercase words containing underscores.
Asked what mover_stop.sh does, it invented a description and dressed it in
real memory facts so it read as authoritative — the exact failure the profile
split exists to prevent. A polite instruction in a system prompt is not a
guard. The rule now leads and is absolute, and a deterministic check repeats
it immediately before the message whenever the question names a shell script,
a SCREAMING_CASE conf key, or Varaverk itself. Detection can only make the
model more cautious, so a false positive costs a redirect, not an answer.
Explicit buttons rather than an automatic router. Misclassifying a Varaverk
question as chat produces a confident invention about the user's system, which
is exactly what retrieval exists to prevent — with buttons there is no hidden
heuristic to be wrong and the strict profile is the default you land on.
Only Varaverk Assistant retrieves; the other two would be carrying passages
that cannot help write a folder-copy script. Memory goes to all three, since
that is what lets chat know the setup without claiming authority over it.
History depth is per profile and set server-side: retrieval costs ~2500 of
16384, so the profiles that skip it can hold a real conversation. Code
Sketcher is told to flag flags it is unsure of, after it invented
rsync --no-overwrite.
A small operator-written file handed to the model at the start of every
conversation — who you are, how this install is set up, what has already been
decided. Injected ahead of the retrieved passages and marked operator-authored
so it outranks anything they contradict, and never cited as a source.
Deliberately not indexed and deliberately under DATA_DIR: it changes
constantly, vector similarity is the wrong way to retrieve things you were
told to remember, and gitignoring it keeps personal notes out of a pushed
repository. The character cap is a context budget — this text costs its share
of 16k on every single turn.
Asked what was wrong, it answered "AI_ENABLED=false" — read from the conf
template, which records the shipped default, while the live value was true.
Passing checks are what tell the model the current value of a setting;
without them a documented default fills the silence. The prompt now states
explicitly that live state overrides any documented default.
The failures this subsystem actually has are configuration drift, so each
check names the setting to change rather than reporting that retrieval
failed. Notably it catches a conf model tag that is no longer installed, and
an index built by a different embedder than the one configured — vectors
from two models are not comparable, and that failure returns confident
nonsense rather than erroring. Diagnostic questions also get recent log
warnings, attached only then because they cost budget the passages need.
Token and poll rather than SSE, so the api layer keeps one response
convention and reuses the pattern manual_sync already proved. History is
capped at three turns because the model is only fully offloaded at 16384
context and unbounded history would cross that silently. The tab exists
only while AI_ENABLED is true, rejected server-side and not merely hidden.