Inspiration
AI assistants are getting more personal — they remember your job, health, finances, and relationships. But most systems treat memory as all-or-nothing: one agent sees everything, or you copy-paste context by hand.
We wanted selective disclosure for AI memory: give each specialized agent only the slice of your life it needs. A health coach shouldn't see salary negotiations; a finance bot shouldn't see therapy notes. Midnight felt like the right fit because it lets you prove what you shared (category + commitment) without exposing the full memory store on-chain.
What it does
Selective Memory AI is a hackathon demo where you pick one of four agents — Health, Career, Finance, or Personal — each with explicit allowed and blocked memory categories.
- Choose an agent and review which memory scopes it can access.
- Click Generate Midnight Access Proof to approve only memories in that agent's categories.
- Chat with the agent (e.g. "What do you know about me?").
- Switch agents and repeat — each agent answers differently because it only sees its approved memories.
The UI makes the policy visible before chat starts. Chat is proof-gated: without a valid grant, the agent refuses to answer. When Midnight is enabled, grants are recorded on-chain via the grantAgentAccess circuit; otherwise the demo uses a deterministic mock proof so judges can try it locally in under two minutes.
How we built it
Stack: React + Vite frontend, Express API, in-memory store for demo memories/grants, optional OpenAI for chat.
Architecture:
- Frontend (
client/src/App.tsx) — single-page flow: agent picker → scope tags → proof button → chat. - Backend — three routes: list agents, generate proof, chat (proof required).
- Memory model — 12 demo memories across four categories (
server/src/seed.ts), each agent scoped to one category. - Proof flow (
server/src/proof.ts) — filters memories by agent category, approves grants in the store, returns proof metadata (proofHash,grantRoot, optionaltxIdfor real Midnight mode). - Chat (
server/src/chat.ts) — only reads granted memories; denies blocked topics; supports mock replies or OpenAI with a system prompt restricted to approved memories. - Midnight integration:
- Compact contract (
contracts/memory-access.compact) —grantAgentAccessrecordsagentId,categoryMask,grantRoot, andtimestampon the ledger. - Commitments —
grantRoothashes approved memory IDs + timestamp off-chain; chat re-verifies before responding. - Phased setup — Docker proof server,
compactcompile tocontracts/managed/, optional preprod deploy withMIDNIGHT_ENABLED=true.
- Compact contract (
Demo path: npm install → npm run dev → open localhost:5173 → pick agent → generate proof → ask "What do you know about me?"
Challenges we ran into
- Making privacy tangible in a 2-minute demo — We had to show different answers per agent without a long onboarding flow, so we invested in clear allowed/blocked tags and a single killer question.
- Midnight toolchain complexity — Node 22+, Docker proof server, Compact compiler, wallet funding, and 30–90s on-chain proof generation meant we needed a mock mode (SHA-256) that still mirrors the real grant shape, with Midnight as the "full" path.
- Keeping chat honest to scope — Even with grants, models can hallucinate cross-category facts; we added server-side scope checks, blocked-topic denials, and system prompts that only include approved memories.
- Grant verification vs. UX — Real ZK grants are slow; we grant memories server-side first so chat still works if metadata steps fail, while Midnight mode re-checks
grantRootbefore replies.
Accomplishments that we're proud of
- End-to-end story: policy → proof → scoped chat in one screen.
- A Compact contract (
grantAgentAccess) that records selective-disclosure grants on Midnight, not just app-level flags. - Four agents with 12 realistic memories that make cross-leakage obvious when you switch agents.
- Works offline-friendly (mock proofs + deterministic chat) and Midnight-ready when env is configured.
- Clean separation: categories as bit masks,
grantRootcommitments, and verify-before-chat for real proofs.
What we learned
- Privacy UX is product design — Users need to see allowed vs. blocked scopes before they trust "private" AI.
- ZK fits selective disclosure — You don't need to put memories on-chain; a commitment + category mask is enough to audit what was shared.
- Hackathon demos need a fast path — Mock mode isn't a shortcut; it's how you teach the idea while Midnight handles the trust anchor.
- Agent memory should be policy-first — Scope should be enforced before the LLM sees any context, not only in the prompt.
What's next for Selective Memory AI
- Stronger witnesses — Prove each memory belongs to
categoryMaskinside the circuit, not only off-chain filtering. - User-owned memory vault — Persist grants across sessions; revoke or time-box access per agent.
- More agents & finer scopes — Sub-categories (e.g. "medications only"), shared agents with least-privilege defaults.
- Wallet-native UX — One-click approve from Lace; show tx/explorer links in the proof panel.
- Production retrieval — Embeddings + RAG still bounded by the same grant verification step before any context hits the model.
Built With
- docker
- express.js
- javascript
- lucide
- midnight-compact
- midnight-network
- node.js
- npm-workspaces
- openai-api
- react
- tailwind-css
- typescript
- vite
- websockets
- zero-knowledge-proofs
Log in or sign up for Devpost to join the conversation.