The Tools card adopted the AI scripts on the host check alone, and api/ai.php only
tested AI_ENABLED in front of ask, so a disabled subsystem still had rows to run and
an endpoint that answered.
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.
A POST the browser demonstrably sent — correct token, correct body — left no
trace: no CSRF termination, no fatal, and no action log. Rejected-before-PHP
and died-inside-the-include are indistinguishable from outside, so the first
statement now records that execution arrived.
There is no nginx access log on this host and the CSRF prepend exits with an
empty body, so a request that never arrived and one that arrived and failed
were indistinguishable — the page just sat at "starting…". The job-file write
was also suppressed with @, which would produce exactly that hang: a token
returned for a job that can never report.
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.