← back to all projects
project no. 1

A private memory library that never confuses an AI guess with a fact.

In development

AI guesses never become facts
  • Suggestions only
    no face is auto-assigned to a person
  • 512-D
    face embeddings, never sent to an LLM
  • 1 bank / user
    isolated long-term memory
  • 0 brokers
    Postgres is the job queue

Why I built it

the problem, minus the buzzwords

Photo apps can find faces, but they don’t know that this face is “Mummy” or that “bhai” and “elder brother” mean the same person. And AI tools that “remember” things mix up what you told them with what they guessed, so you can’t tell which answers to trust. Reject a wrong guess and it comes back next week.

I wanted a memory app where what you confirmed, what was only suggested and what you rejected stay separate all the way from upload to search.

How it works

upload once, the worker does the rest
  1. Upload1

    Next.js app; files stream through FastAPI into Oracle object storage, hashed on the way in.

    #client

  2. Job queue2

    Every change and its follow-up job commit in one Postgres transaction; workers claim jobs with SKIP LOCKED.

    #postgres

  3. Worker3

    EXIF + thumbnail, faces (YuNet + AuraFace), pgvector matching, scene descriptions, document text.

    #pipeline

  4. Questions4

    “Is this Mummy?” Answers are stored as confirmed, rejected or skipped, never merged.

    #review

  5. Memory & search5

    One Hindsight document per file and person, rendered from the database; results are re-checked before showing.

    #recall

  • +Sign-in with Better Auth (Google + email codes); FastAPI only trusts short-lived JWTs it verifies against the JWKS.
  • +Every table carries user_id and child rows use composite (id, user_id) keys, so the database itself refuses cross-user references.
  • +Each worker stage is independent: a failed scene description never loses the faces found in the same photo.

Built with Next.js, FastAPI, PostgreSQL, pgvector, Better Auth, Hindsight, YuNet + AuraFace, OpenAI, Oracle Object Storage, Docker.

Decisions I made

and why. mostly why.
  1. 1.Guesses stay guesses

    Unknown isn’t false, skipped isn’t rejected, inferred isn’t confirmed. Face matches are only ever suggestions, and a rejected fact is kept as a tombstone so it can’t be suggested again.

  2. 2.The database is the truth, memory is a projection

    Hindsight never sees raw events. It gets one document per file and person, re-rendered from current state. Search results from stale or deleted documents are dropped, and a generated answer is shown only if every memory behind it still checks out.

  3. 3.Postgres as the queue

    Jobs are enqueued in the same transaction as the change that needs them, so nothing is ever saved without its follow-up work. No extra broker to run or lose messages.

  4. 4.Understand how people actually talk

    Relationship words like “bhai”, “jiju” and “Mummy” map to canonical relations, so “who is my bhai?” is answered straight from your records, even when the memory engine is down.

next up (you’ve come this far)
BizAssist →
A multi-agent business assistant that loads only the tools it needs.