This guide walks you through setting up a working local instance of the LLM Memory Donation Study platform.
- Python 3.12+
- uv package manager (install instructions)
On macOS (Homebrew):
brew install postgresql@17
brew services start postgresql@17PostgreSQL 17 is a keg-only formula, so you must add its binaries to your PATH. Add this line to your shell profile (~/.zshrc or ~/.bashrc) and restart your terminal:
echo 'export PATH="/opt/homebrew/opt/postgresql@17/bin:$PATH"' >> ~/.zshrc
source ~/.zshrcVerify PostgreSQL is running:
pg_isreadyYou should see accepting connections. If not, run brew services start postgresql@17.
git clone <repo-url>
cd MemoryHole
uv sync --all-extras --group devThis installs:
- Core: Django, psycopg, django-htmx, spaCy
- Dev tools: pytest, pytest-django, ruff, mypy, django-stubs
- E2E testing: playwright
Running uv sync without flags installs only core dependencies.
The platform uses spaCy to flag third-party names in memory entries. Download the medium English model:
uv run python -m spacy download en_core_web_mdIf disk space is limited, en_core_web_sm works as a fallback (loaded automatically if en_core_web_md is unavailable), but detection quality is lower.
createdb memory_donationThe database connection is configured in memory_donation/settings.py and defaults to memory_donation on localhost with no password (peer/trust auth).
If you need to customize the connection or other settings, set environment variables before running Django commands:
| Variable | Default | Description |
|---|---|---|
DJANGO_SECRET_KEY |
Dev fallback provided | Session/CSRF signing key |
DJANGO_DEBUG |
True |
Debug mode |
DJANGO_ALLOWED_HOSTS |
localhost,127.0.0.1 |
Comma-separated hostnames |
uv run python manage.py migrateThis creates all 9 core tables: Study, Participant, PreDonationSurvey, MemoryUpload, MemoryEntry, AccuracyAnnotation, EditAction, PostReviewSurvey, and DonationConsent.
The platform requires at least one active Study in the database. You can create one directly from the command line:
uv run python manage.py shell -c "
from donation.models import Study
Study.objects.create(
title='LLM Memory Donation Study',
description='Understanding what LLM memory systems store about their users.',
consent_form_version='1.0',
is_active=True,
)
print('Study created.')
"Or create it via the admin interface at /admin/donation/study/add/ (requires a superuser -- see below).
uv run python manage.py runserverOpen http://localhost:8000 in your browser. You should see the landing page.
uv run python manage.py createsuperuserFollow the prompts to set a username and password. The admin interface is at /admin/ and shows all models with filters and search.
The platform walks participants through a linear 10-stage flow:
- Landing (
/) -- Study description, "Begin" button - Consent (
/consent/) -- Informed consent with 4 required checkboxes - Pre-Survey (
/survey/pre/) -- Provider usage, expectations, comfort scales, demographics - Export Instructions (
/instructions/) -- Tabbed instructions for Claude, ChatGPT, Gemini, Grok - Upload (
/upload/) -- Paste or upload memory export text - Parsing Review (
/review/) -- Confirm parsed entries look correct - Annotation (
/annotate/) -- Rate each entry for accuracy, category, source, sensitivity, surprise - Editing (
/edit/) -- Keep, edit, or redact entries before donation - Post-Survey (
/survey/post/) -- Comfort and behavioral intention measures (mirrors pre-survey) - Final Review + Thank You (
/final/,/complete/) -- Summary, consent tier selection, completion
Each stage is gated -- participants cannot skip ahead. Progress is tracked via session tokens (no login required).
uv run python -m pytest tests/ -vCovers models, views, middleware (stage gating), parser pipeline (all 4 providers + NER + classifier + sampler), and form validation.
Note: Use
python -m pytestrather than callingpytestdirectly. The directpytestentry point may not resolve correctly depending on your virtual environment configuration.
The E2E script walks through the entire participant flow in a headless browser, takes screenshots at every stage, and reports errors.
# Install Playwright browsers (first time only)
uv run playwright install chromium
# Run with the dev server already running in another terminal
uv run python tests/e2e_walkthrough.pyScreenshots are saved to screenshots/. The script:
- Fills out all forms with test data
- Uploads the sample Claude export from
fixtures/claude_export_sample.txt - Annotates all parsed entries
- Tests redact and edit actions
- Completes the full flow through the thank-you page
| Problem | Solution |
|---|---|
createdb: command not found |
PostgreSQL bin is not on your PATH. Run export PATH="/opt/homebrew/opt/postgresql@17/bin:$PATH" or add it to your shell profile. |
connection refused on database commands |
PostgreSQL is not running. Run brew services start postgresql@17 and verify with pg_isready. |
uv run pytest fails with "No such file or directory" |
Use uv run python -m pytest instead. |
VIRTUAL_ENV does not match warning |
Safe to ignore. This appears when another Python environment is active; uv run uses the project .venv regardless. |
| spaCy model not found | Run uv run python -m spacy download en_core_web_md. |
MemoryHole/
├── memory_donation/ # Django project settings
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── donation/ # Main app
│ ├── models.py # 9 data models
│ ├── views.py # All stage views
│ ├── urls.py # URL routing
│ ├── forms.py # Form classes
│ ├── middleware.py # StageGateMixin, session helpers
│ ├── admin.py # Admin registration
│ ├── parsers/ # Memory export parsing pipeline
│ │ ├── detector.py # Provider auto-detection
│ │ ├── claude.py # Claude adapter
│ │ ├── chatgpt.py # ChatGPT adapter
│ │ ├── gemini.py # Gemini adapter
│ │ ├── grok.py # Grok adapter
│ │ ├── generic.py # Fallback line-by-line parser
│ │ ├── ner.py # spaCy NER for third-party PII
│ │ ├── classifier.py # Rule-based category classifier
│ │ ├── sampler.py # Stratified sampling (>50 entries)
│ │ └── pipeline.py # Orchestrates full pipeline
│ └── templates/donation/ # Django templates (HTMX + Alpine.js)
├── tests/ # pytest unit tests + E2E script
├── fixtures/ # Sample exports and attention checks
└── pyproject.toml # Dependencies and tool config