Minimal local test slice for the rewrite spec.
Production-facing deployment and operations docs now live here:
- Production Deploy Runbook
- Operator Recovery Runbook
- Apache Vhost Example
- Production Env Example
- Production Deployment Checklist
The default local runtime now bootstraps and uses state/local_repository automatically. On first run it copies the committed fixture seed into that writable git repo, so thread/reply/bootstrap writes work without setting FORUM_REPOSITORY_ROOT.
Rebuild the SQLite read model:
php scripts/rebuild_read_model.phpBuild Apache-friendly static HTML artifacts into public/:
php scripts/build_static_artifacts.phpStart the local PHP server:
./v3 startCreate or update the local private config for Dedalus post analysis:
./v3 private-configFor this checkout, the default local file is /home/wsl/forum-private/secrets.php. To update only the Dedalus API key without putting it in shell history:
printf '%s\n' "$DEDALUS_API_KEY" | ./v3 private-config --api-key-stdinThe default Dedalus post-analysis prompt is stored in prompts/dedalus_post_analysis_system.txt. Set DEDALUS_POST_ANALYSIS_PROMPT_PATH in the private config to use a different text file; relative paths are resolved from the project root.
For Apache/shared-host deployment, public/.htaccess is now part of the intended runtime model:
- serve existing files and directories directly
- serve queryless cookie-free sibling
*.htmlartifacts directly for/,/instance/,/activity/,/users/,/threads/<id>,/posts/<id>, and/profiles/<slug> - fall back to
public/index.phpwhen no static artifact exists
That matches the planning assumption that Apache should serve static-safe anonymous HTML directly and use PHP only as fallback.
The repo-owned deployment contract is now documented in the production runbook. What remains before a real production launch is mostly host-side validation on the actual Apache target.
Open these routes:
http://127.0.0.1:8000/http://127.0.0.1:8000/about/http://127.0.0.1:8000/threads/root-001http://127.0.0.1:8000/posts/root-001http://127.0.0.1:8000/activity/http://127.0.0.1:8000/users/http://127.0.0.1:8000/activity/?view=all&format=rsshttp://127.0.0.1:8000/instance/http://127.0.0.1:8000/profiles/openpgp-0168ff20eb09c3ea6193bd3c92a73aa7d20a0954http://127.0.0.1:8000/user/guesthttp://127.0.0.1:8000/compose/threadhttp://127.0.0.1:8000/compose/reply?thread_id=root-001&parent_id=root-001http://127.0.0.1:8000/account/key/http://127.0.0.1:8000/api/http://127.0.0.1:8000/api/list_indexhttp://127.0.0.1:8000/api/get_thread?thread_id=root-001http://127.0.0.1:8000/api/get_post?post_id=root-001http://127.0.0.1:8000/api/get_profile?profile_slug=openpgp-0168ff20eb09c3ea6193bd3c92a73aa7d20a0954http://127.0.0.1:8000/llms.txt
The default server uses state/local_repository when FORUM_REPOSITORY_ROOT is unset. Override it with FORUM_REPOSITORY_ROOT=/path/to/repo if needed.
Compose routes now use submit-time browser identity bootstrap for brand-new users:
- no keypair is generated on page load
- on the first real submit, the browser prompts for username, generates an OpenPGP keypair, publishes the public key in the background, sets the identity-hint cookie, and then continues the original post submit
- existing browser-local keypairs skip regeneration
- if browser generation/bootstrap fails, the draft stays intact and
/account/key/remains the manual fallback
If you want to initialize that writable repo explicitly ahead of time:
php scripts/init_local_repository.php
FORUM_REPOSITORY_ROOT=/home/wsl/v3/state/local_repository php scripts/rebuild_read_model.php
FORUM_REPOSITORY_ROOT=/home/wsl/v3/state/local_repository ./v3 startStatic HTML artifacts for anonymous queryless route hits default to state/static_html. Override that location with FORUM_STATIC_HTML_ROOT=/path/to/static_html if you want to test direct artifact serving.
The current PHP front controller supports both layouts:
- Apache/public sibling artifacts such as
public/threads/root-001.html - the older separate
FORUM_STATIC_HTML_ROOTfallback path for local testing or deployments that keep generated artifacts outsidepublic/
Set the local identity-hint cookie:
curl -X POST "http://127.0.0.1:8000/api/set_identity_hint?identity_hint=openpgp-demo"Write API examples:
curl -X POST "http://127.0.0.1:8000/api/create_thread?board_tags=general&subject=Hello&body=Thread%20body"
curl -X POST "http://127.0.0.1:8000/api/create_reply?thread_id=root-001&parent_id=root-001&body=Reply%20body"
curl -X POST --data-urlencode "public_key@tests/fixtures/parity_minimal_v1/records/public-keys/openpgp-0168FF20EB09C3EA6193BD3C92A73AA7D20A0954.asc" "http://127.0.0.1:8000/api/link_identity"
# low-level/manual fallback:
curl -X POST --data-urlencode "public_key@tests/fixtures/parity_minimal_v1/records/public-keys/openpgp-0168FF20EB09C3EA6193BD3C92A73AA7D20A0954.asc" "http://127.0.0.1:8000/api/link_identity?bootstrap_post_id=root-001"Approval helper examples:
./v3 start
./v3 approval seed openpgp:0168ff20eb09c3ea6193bd3c92a73aa7d20a0954
./v3 approval approve openpgp:0168ff20eb09c3ea6193bd3c92a73aa7d20a0954 openpgp:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRun the current parser, rebuild, and app smoke tests:
./v3 test