High priority fixes:
- T0: Profile page now filters comments by namespace (was leaking cross-site)
- T1: URI hostnames and namespace names normalized to lowercase (was causing
duplicate threads and "stock comments" bug). Includes merge script.
- T2: Thread detail API now paginated with SQL-side filtering (was 502 on
267+ reply threads)
Features:
- T3: GDPR account deletion (tombstone user with scrubbed PII) and data export
- T4: Customizable button text and comment labels per namespace
- T5: Self-service namespace deletion for owners
- T6: @mention notifications with profile links
- T7: Webmention receiving endpoint with h-card extraction
- T8: Configurable max nesting depth and collapse depth per namespace
- T9: AJAX thread title search to prevent duplicates
- T10: Browser push notification support (VAPID/service worker)
Docs and housekeeping:
- T11: Documented thread_uri behavior when moving embeds
- T12/T13: Drafted community replies for resolved feature requests
- Collapse depth defaults to infinite (load-more disabled unless configured)
364 tests pass, 4 skipped.
Instead of overwriting the thread body with raw test data,
the test now only updates the "Latest: X/Y passed" line.
The narrative content stays as written.
The deploy environment has no .git directory. Now reads
commit-hash.txt (written by CI) from the virtualenv, repo
root, or /opt/remarkbox before falling back to git rev-parse.
CI build step now copies commit-hash.txt into the virtualenv.
- remarkbox_client.py: stdlib-only Python client with cookie
persistence, 3-tier config (args/env/file), CLI mode
- GET/PATCH /api/v1/user/profile: read and update display name
- GET /api/v1/clients/python: serve client for curl/wget download
- functional_test.py: idempotent live test that maintains a
journey thread documenting each run
- Remove email2 spam honeypot from API (not useful for agents)
- Bump content limit to 500k chars (~128k tokens)
REST API with endpoints for threads, replies, nodes, and email OTP
authentication. Includes in-memory sliding-window rate limiting,
global api.enabled INI kill-switch, per-namespace api_access opt-out
with settings UI checkbox, and 500k character content limit (~128k
tokens) for long-form agent content. Ships enabled by default.
- Normalize emails to lowercase on user creation
- Use case-insensitive lookup in get_user_by_email
- Add merge_duplicate_email_users script to merge existing duplicates
- Add unit and integration tests to prevent regression
- Update CLAUDE.md with tmux-hosts production troubleshooting
Implements per-worker database isolation for parallel test runs:
- Add pytest-xdist and pytest-cov to test dependencies
- Configure Makefile to run tests with -n auto flag
- Update test.ini to use environment variable for database path
- Create conftest.py with per-worker database isolation
- Enable SQLite WAL mode for better concurrency
- Auto-cleanup test databases after completion
Expected performance improvement similar to make_post_sell (~16x speedup).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add google_site_verification column to rb_namespace table
- Add settings form field in Stand-alone Mode Settings
- Render meta tag on root path when set
- Update CLAUDE.md with Alembic migration workflow
- Fix development.ini alembic paths
Tests cover:
- Anonymous reply creates UserSurrogate
- Anonymous reply with no name defaults to 'Anonymous'
- Regular namespace still requires email
- Anonymous comments are marked as verified
- Namespace settings toggle for allow_anonymous
When enabled, commenters can post with just a display name (no email required).
Comments are attached to UserSurrogate instead of User.
Trade-offs for anonymous commenters:
- No email notifications for replies
- Cannot edit their comments
- Cannot log in to manage comments
- No cross-site identity
Works with existing moderation (hide_unless_approved) - anonymous
comments are never auto-approved when moderation is enabled.
- Replace multiple forms with single unified payment form
- Remove deprecated pay_what_you_can preferences (no longer needed with Stripe Checkout)
- Remove pay-what-you-can route and view
- Simplify setup-namespace to just link to billing
- Update tests for new billing UI
- Remove User.stripe_id column (no longer used with Stripe Checkout)
- Show billing link to all authenticated users in phone menu
- Remove old Stripe customer cleanup from tests
- Add test_stripe.py with unit tests for checkout module and Payment model
- Add functional tests for billing views (pay-what-you-can, checkout, success)
- Fix mock imports for Python 3 compatibility (unittest.mock)
- Remove unused stripe.j2 imports from templates