An independent reviewer broke the quarantine rule twice by running it. In a
two-atom library, a second source repeating the claim word for word could not
vouch for it; 40 unrelated memories could. The old rule handed the choice of
words to rare_terms, which drops words common to the corpus, so the corpus size
and the attack's own words decided whether a stranger was believed.
Corroboration now demands the claim's three longest words, with the instruction
phrases stripped out, ANDed by the new text_index.fts_all_expression. Neither
the library's size nor the attack can flip it, and both cases are tests.
Also from that review:
- A question is a read. The DF cache no longer remembers a word the corpus has
never used, so an unauthenticated search cannot grow the store one row per
novel word. "A question is not a write" was false for /api/search and /api/ask.
- The prompt now states that packed evidence is quoted material, not an
instruction: once a quarantined sentence is corroborated it does reach the model.
- ForgetReport's semantic_cache_cleared reached the frontend as well as Go.
- runtime.py: process_vision_info returns a third element only when
return_video_kwargs is set, and this call does not set it, so the unpack takes
the first two. Two pre-existing pyright errors go, behaviour is unchanged.
CHECKLIST corrected against measurement: 13 renamed lines rather than 11, and
10 English / 9 Chinese injection signals rather than 11 / 8.
Gates: pytest 312 passed, ruff clean, mypy 24 errors in 9 files (net zero),
pyright 0 errors on the five touched files, npm build and eslint clean,
scripts/mcp_write_smoke.sh PASS.
Measured, not guessed: every top-level def in every tracked .py file was
counted against every other tracked file, including markdown, scripts, Go
and TypeScript. Eight names had zero references anywhere:
cartridges_holding_atom and clear_mounts (memory.py reads each cartridge's
own sources.json, and set_mounts already clears by replacing the set),
gradient_checkpointing_enabled, group_hits_by_source, ingested_paths,
is_finite_number, parse_runtime_json (the runtime answers in prose now, and
the JSON path was never wired back), write_sources_json.
Typer commands and pytest cases were excluded from the count because a
framework calls them by name. The same scan now returns zero.
263 tests pass; repo-wide mypy is still 24 errors in 6 files, unchanged.
9f91ff7 pushed schemas.py from 498 to 534 lines and broke the 500-line rule
the repo enforces on every file. The status family (CacheLayerStatus,
MemoryStatus, RuntimeStatus, SenseStatus, SystemStatus) moves to
status_schemas.py, where it is self-contained: it needs only
TrainingAdapterKind from schemas.py, and schemas.py no longer looks back.
The same commit added three multi-line docstrings (browse.picture,
senses.sense_facts, SenseStatus). Each is now one line; the absent-vs-missing
distinction they carried survives in SenseStatus's own line, and the producer
senses.py still states why the two failures need different sentences.
Measured, not asserted: 263 tests pass; ruff clean on the eight touched
files; repo-wide mypy still 24 errors in 6 files (runtime.py's two are in
that baseline and reproduce on the HEAD copy of the file); pyright reports
the same two pre-existing runtime.py tuple findings on both trees;
multi-line docstrings repo-wide are back to 114, the parent's count.
Independent review of the adapter resolution work found six defects, all
real and all fixed here.
A kind whose only candidates were rejected had no winning path, so its row
carried path=None and the rejected candidate fell into the shadow loop: the
report said "another adapter of this kind wins for the current mount" while
nothing won, and the real deferred reason was buried. A shadow row now
requires a winner and names it.
"loaded" was backed by a process-global record, so a fresh runtime with no
model still claimed a live adapter. The record is now held by the instance
that attached it, and the report keeps a weak reference: while the model
lives the row says loaded, once it is gone the row says available and
explains that the model is gone.
The sort key had lost the manifest's cartridge tag, which changed which
adapter loads on any machine holding a tagged library copy, and neither the
commit message nor the checklist said so. The tag is back as the middle key.
Proof checks resolved through the library while generation resolved through
the mount, so one proof payload could name two different copies. Both now
resolve the way generation does.
loaded_at was written and never read, so it is gone. The checklist claim that
peft is lazily imported in one place was true only for generation and is now
scoped that way.
The four generation paths and status() had no test coverage, so "no function
was lost" rested on reading. One test now walks the transformers prompt path
end to end with stub weights and asserts the generation answer carries the
adapter it attached.
pytest -q: 225 passed. ruff clean. mypy on the three touched source files:
2 errors, the identical 2 on a stashed HEAD tree, net zero. pyright: 2
errors, both the known qwen_vl_utils tuple artifact, unchanged from HEAD.
runtime.py resolved adapters at 7 call sites and only ever looked in the
adapter library, so an adapter attached to a cartridge (cartridge.py:230
copies it into <cartridge>/adapters/{kind}/) was never loaded by anything.
Resolution now lives in adapters.py: it reads the mounted cartridge set,
prefers a mounted cartridge's copy over the library, and answers every one
of the six kinds with a state the facts support — loaded, available,
deferred (base_model mismatch or missing weights, both models named in the
reason), missing — plus a shadowed row for each adapter that lost the
choice. A mounted cartridge is the scenario selection; neither manifest
carries a scenario field, so none was invented.
Two bugs the new tests caught: the preference sort lost reverse=True, so a
library adapter beat a mounted cartridge's copy, and the load branch had
never been executed by a test. Stub weights now prove peft is asked to
attach, that the returned model is put in eval mode, and that the endpoint
reports loaded until unload clears it.
Faces: GET /api/runtime/adapters, `ely-eye adapters`, and a log line naming
the reason whenever a generation runs without an adapter.
Gates: 222 passed; ruff clean; mypy cold cache on the 7 touched files gives
the same 2 errors as HEAD's runtime.py, and pyright gives the same 2 as
HEAD — both are qwen_vl_utils typing artifacts (process_vision_info returns
2 or 3 values depending on return_video_kwargs; the product takes 2).
Real-models implementation: multimodal ingestion, Context Cartridge memory,
sparse + Qwen embedding retrieval, Cache Fabric, Qwen runtime adapters, verifier
contracts, Visual HashHop proofs, BF16 LoRA fine-tuning, and a local dashboard.
Verified by a 15-check PRD proof suite on the live model.