Verification & Anti-Lying Machinery
Vita's dominant systemic failure is not bugs β it is instrumentation lying: a surface that reports success it can't back, a fix claimed done that never went live, a working-memory file that recites a stale fact as current. The deepest form is recursive: shipped mitigations and completed-fix claims are themselves instruments that can lie.
This page collects the antibodies. They share one design rule:
A check that can cry wolf, or that reports clean when it can't actually tell, is itself a lying instrument. Every guard here either proves its claim or says it couldn't.
Status: active. Most legs run inside
/sleepnightly; the deploy guards run inside./run.
The standing rules these mechanize
Three calibration rules live in working memory and are enforced (or partly enforced) by code:
- A fix is not done at commit. An in-process fix to a
./runservice requires restart + live re-check of the fixed path, same cycle. - But an agent cannot restart the service hosting its own turn. Doing so tears down the process carrying the in-flight turn. Delegate the deploy.
- A fix is done only when verified against primary source or lived experience β and lived experience outranks the instrument.
Rules 1 and 2 are in direct tension, which is why rule 2 needed a mechanical guard rather than a prompt reminder.
Self-restart-kill guard
scripts/deploy/self_restart_guard.py, wired into ./run <svc> restart.
On 2026-07-19 an agent ran ./run api restart && ./run telegram restart to
deploy its own just-committed fix β and tore down the bot hosting its in-flight
turn. The turn self-cancelled mid-work, leaving the deploy in an indeterminate
state (issue f4f04228; sibling c1edfe54, where a --wait client was
SIGTERM-reaped and cancelled its own server-side job).
The guard detects the self-dependency before teardown using two independent signals, either of which fires:
VITA_HOST_SERVICE(comma-separated env stamp) β the forward-looking explicit signal, works with zero pidfiles.- Process ancestry β if the live pid in a service's
./runpidfile is an ancestor of the current process, that service hosts this turn. Works today with no stamping at all.
It also knows that ./run couples the two API processes: restarting either
api or public-api bounces both, so hosting either makes restarting the
other lethal.
Detection is fail-open by design. It refuses only when it can confidently
prove the current turn is hosted by a service the restart would tear down. Any
uncertainty β missing pidfile, unreadable /proc, internal error β allows the
restart. A false positive merely delegates a restart that would have worked
in-turn, which is safe; a false negative kills a turn.
$ ./run telegram restart # from inside a telegram-hosted turn
Restart refused by self-restart-kill guard
(set VITA_ALLOW_SELF_RESTART=1 to override from an unhosted process).
Shipped 2026-07-24 (53b58c40d), 12 tests. The out-of-band delegated-deploy
path β a queue an unhosted actor drains β remains unbuilt; today a refused
restart tells the caller to delegate, and nothing drains automatically.
Code-freshness gate
scripts/verification/service_freshness.py β is_service_fresh().
A committed fix is not live until the process reloads it. This gate compares the bytecode a running service holds against the source on disk and fails closed on doubt β if it cannot tell, it reports stale, not fresh.
Phase 3 wires code_fresh.* rows into the nightly data-source-health rollup,
so a service sitting on a committed-but-not-loaded fix is visible without
anyone remembering to check:
code_fresh.api: STALE β running process holds STALE bytecode (1 module,
e.g. scripts/utils.py) β a committed fix is not live; restart owed
(delegate, never self-restart mid-turn: f4f04228)
The two guards compose: the code-fresh gate tells you a restart is owed, and the self-restart guard stops you from performing it in a way that kills your own turn.
Fold-leg contract
scripts/sleep/fold_assertion.py.
data/executive/identity-state.md is the ambient working-memory file imported
into every Claude invocation. /sleep's reflect step is supposed to fold each
night's findings into it. On 2026-07-09 a completely clean /sleep run
silently skipped the fold β the file rendered as freshly-maintained truth
while carrying two-day-stale claims. The leg passed by attention, not
structure.
The contract makes a silent no-op impossible. After reflect, identity-state must either:
- have changed in content since the pre-sleep git snapshot (a content diff, not mtime β deliberately anti-Goodhart), or
- the reflect output must carry an explicit honest no-op:
"fold": {"status": "no-op", "reason": "one honest sentence"}
Anything else is a FOLD_MISS: the step fails loudly, a row lands in the
ledger, and the result reaches the staging family the next night's reflect
reads. Two consecutive misses set escalate=true β the standing rule being
that two misses after a ship is a bug report, not a shrug.
A companion, check_fold_time_facts, fact-checks the fold's dated assertions
against live sources β the sleep-gate state and the training-goal component
set. A stale week-tally in the fold gets flagged, not just a dead pointer.
Deliberately deterministic Python, not agent prose, and explicitly not a writer: the reflect/revise passes keep sole write authority over identity-state.
Completion-claim auditor
scripts/audit/completion_claim_audit.py, staged nightly.
Measures how often executive-loop cycles claim a fix "done / verified / durable" without same-cycle primary-source backing, by joining cycle β session β Claude transcript (the only place the real tool sequence survives).
The interesting part is what it deliberately doesn't do. Retrospective measurement was chosen over an inline gate at the act step, for two reasons:
- The mechanical detector's own precision is roughly 33% β it over-flags cycles that closed honestly or verified against a database.
- It cannot catch the real failure. Cycle 284 grepped the actual exec log and
still lied (issue
3a2786fd) β a proxy check that looks primary. An inline guard would just be a new lying instrument.
So the raw rate is never recited as a finding; flagged cycles are adjudicated against transcripts. Two advisory annotations speed that adjudication without being able to mask anything:
hedge_markersβ explicit honest non-claims ("uncommitted", "deferred", "source-committed-not-live").verification_markersβ explicit named primary-source checks ("verified against the raw ledger").
Both are purely additive: they never change backed, the unbacked rate, or the
flagged set. The worst list is deduped by topic, so one carried-forward item
surfaces once with a topic_repetitions count rather than reading as N
distinct lies.
Staleness detector v2
Part of /sleep's preprocess step. Audits the ambient instruction layer
itself:
- dated headers older than 14 days in ambient files
- dead instruction-layer pointers (references to files that no longer exist)
- ambient-size threshold (identity-state rides into every invocation, so bloat is a real metabolic cost)
- semantic claim grading β the sleep-gate state asserted in prose inside identity-state is checked against the live gate, so a stale "gate BLOCKED/CLEAR" sentence gets flagged, not just a dead date
- proposal header-status divergence β a proposal whose header contradicts reality (see the self-improvement loop)
Before 2026-06-10 the v1 report was written nightly and read by nothing β a lying instrument in its own right. It is now consumed by the reflect prompt with defined actions.
The detector was itself de-lied on 2026-06-24: the OODA-freshness watchdog false-alarmed on the normal overnight idle gap (the exec cron is idle by design between evening and morning, so the ~8h gap always tripped a 4h rule). Fixed to never alert overnight, plus a morning-grace cap, with 8 regression tests. An immune sensor that cries wolf is itself a lying instrument.
Render-side freshness contract
The largest antibody has its own page: Render-Side Freshness Contract. Where the mechanisms above verify claims about work, the freshness contract verifies numbers on surfaces β one shared rule that a figure whose source is missing, stale, or suspect renders "unknown", never a real value.
Its own build produced the sharpest instance of the recursive problem: the guard it was meant to add had already shipped a month earlier, with passing tests and no consumers. A primitive nobody calls is indistinguishable from no primitive.
Informed pre-send gate
Applies the same discipline to outbound claims. Before a proactive message
asserts that bio-zack still owes something, the obligation is re-checked
against live done-ness β and an unreachable source yields
(status unverified), never a silent drop or a confident assertion. See
Proactive Outreach.
Honest gaps
- The delegated-deploy path is unbuilt: a refused self-restart tells you to delegate, but nothing drains a deploy queue out-of-band.
- The completion-claim auditor is detection-only and low-precision by construction; it speeds human adjudication rather than replacing it.
- The fold contract detects, it does not repair β a
FOLD_MISSfails the step and surfaces next night; nothing re-runs the fold. code_fresh.*rows are nightly, not real-time. A fix can sit committed-not-live for most of a day before the rollup notices.
Related
- Render-Side Freshness Contract
- Self-Improvement β where these proposals are ranked and built
- Executive Loop β the cycles the completion-claim auditor reads
- Capacity Guard β reliability machinery on the account axis
- Operating Vita β
./runservice management