Files
qtalker---/backend/app
Indiana d37bb71e5d feat: the lens — the camera as a channel the dead look through
A new séance mode. The seeker opens their camera, presses "let it look",
and the entity speaks about what is ACTUALLY in the room — the configured
chat model (minicpm-v4.5:8b) is vision-capable, so this is real perception,
not invented description. Same principle as every other channel here: real
measurement first, interpretation second.

Verified live end-to-end through the real WebSocket: given a synthetic room
(pale doorway, red flame on dark boards), "Bessie L. Carter" reported the
gray rectangle and red square on a dark surface with faint shadows, then
misread it as her pen feeling heavy the night before Mr. Edgerton's birdseed
arrived. Accuracy followed by wrongness, which is the whole effect.

Privacy is the load-bearing design constraint, not a footnote:
- "Camera open" and "the entity saw something" are deliberately separate
  states. Opening the lens transmits NOTHING; only an explicit press sends
  one still. There is no timer and no background capture path.
- Frames are downscaled to 768px and JPEG-compressed client-side, then
  passed to the model and dropped. Never written to disk, never logged,
  never attached to an event row — only the resulting utterance is stored,
  exactly like any other thing a spirit says.
- The prompt forbids describing faces or guessing anyone's identity, age or
  appearance; a person present is spoken of only as a presence.
- A closed lens is covered by an opaque veil in the UI, so there is never
  ambiguity about whether the camera is live.

Robustness:
- CameraEye carries the same generation guard the EVP listener needed:
  closing during the permission prompt releases the late-arriving stream
  instead of letting the camera go live after teardown.
- Failures are classified (denied / insecure / absent / busy / unknown)
  rather than always blaming the seeker for a refusal.
- Scrying is the heaviest request this app makes of a CPU-only Ollama box,
  so it gets the tightest limiter of any channel (4/min/user, 8/min/IP).
- Frames are size-capped BEFORE reaching the queue, and a vision failure
  emits an error frame instead of killing the socket — both covered by
  tests asserting the model was never called.

10 new frontend tests, 5 new backend tests. 385 frontend + backend suites
pass; i18n parity holds across both languages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 02:08:02 +00:00
..