Repository navigation
Align docs with the code and the production host - #71
Merged
Merged
Conversation
AGENTS.md and the RUNBOOK told operators to deploy with `git pull` and `just build-release` in ~/pensieve and to roll back with `git checkout HEAD~1`. Production does not work that way: every Pensieve service runs a release build that a systemd drop-in selects, and the checkout is behind master with live uncommitted edits. The docs also invited `just ch-migrate-all` (replays 009's TRUNCATE and other drops), said 016 was never applied, and described the base schema as if it were production. - AGENTS.md and RUNBOOK: what actually runs, the release-dir deploy and rollback pattern, who reads /etc/pensieve/pensieve.env, Postgres being manual-only, current crate list, env vars for serve and preview - ops/systemd/dropins/: copies of the production drop-ins; add the archive-admission Kuma units and script that only existed on the host - migrations README, base schema header, justfile: ch-migrate-all is for empty databases only; record that 016/017/018 are applied, when each projection was dropped, and that a fresh install matches production except for the events_local projections - README, env templates, serve README: nonexistent flags, .env loading, unused variables, required POSTGRES_ANALYTICS_PASSWORD, API behaviour - design notes: status banners where plans and increment notes went stale - comment-only fixes in ops/production configs; fix the analytics-build recipe, the INVENTORY_ONLY override in the campaign runbook, and the stale default bind address in a serve doc comment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A controlled ingester stop at 06:04 UTC overlapped the hourly and 6-hourly refreshable-view rescans, ClickHouse inserts slowed ~7x, and the 90 s stop timeout killed the process mid-index. The ingester now runs the PR #72 build with a 15-minute stop timeout. - RUNBOOK: avoid stopping during :00-:07 UTC; how to find and repair ClickHouse gaps after a killed shutdown without double-counting views - drop-in records and run tables: negentropy-ba0c4a1 build, new stop-timeout.conf Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The docs no longer describe how Pensieve runs, and some of them would lead an operator or agent to do the wrong thing on production:
git pull+just build-releasein~/pensieveand to roll back withgit checkout HEAD~1. No service runs~/pensieve/target/release/. systemd drop-ins point each one at a release build, and the checkout is 29 commits behindmasterwith uncommitted edits that are live: Compose andarchive-syncuse them.just ch-migrate-allas "run all pending migrations". Nothing records which migrations have run, so it replays all of 001–015 on the live database, including the drop/rebuild migrations and 009'sTRUNCATE+ backfill. The migrations README says 016 "has not been applied to production" (it was, on 2026-07-27). The 017 rollback has no warning that it is no longer cheap now that 018 has run.docs/clickhouse_self_hosted.sqlreads like the production schema. Productionevents_localhas no projections.--import-relays-csv) doesn't exist.pensieve.envis said to configure the ingester (it doesn't). Theanalytics-buildrecipe is broken.Fix
These are doc and comment changes plus repo copies of the production units. I did not change anything on production, and I did not touch the host's checkout or its local edits.
ops/RUNBOOK.md:releases/<component>-<sha>/→ drop-in → restart → check/proc/<pid>/exe.10-release.conf, as its own comment suggests, would start a 2026-07-27 preview build that full-scansevents_local.pensieve.env.PREVIEW_COMPACT_LOOKUPSandPREVIEW_DISABLE_PROJECTIONS.ops/systemd/dropins/: copies of the production drop-ins, with a README. They contain no secrets: the blocked giftwrap recipient pubkey is already incrates/pensieve-ingesttests. I also added thepensieve-archive-admission-kumaservice, timer and script, which until now existed only on the host. They are copied verbatim.ch-migrate-allis for empty databases only. This is stated prominently in all three places and in AGENTS.md.events_by_kindfor fresh installs still holds.--setenv INVENTORY_ONLY=1is overridden by the env file'sINVENTORY_ONLY=0, so the "read-only" step would have run the full campaign. It now uses/usr/bin/env.ops/analytics.env.example: the Postgres socket address could not work. It now uses127.0.0.1.env.production.example: addedPOSTGRES_ANALYTICS_PASSWORD, which is required. Without it,docker composerefuses to start; I verified this locally.just run-ingest -- --helpcorrected tojust run-ingest --help.analytics-buildnow passes--bin.env.local.exampleand the serve README:/stats/engagementreturns 503 unless served from Postgres,/stats/eventsdefaults to a 30-day window, and the error codes table is complete.ops/production. I validatedcompose config,promtooland the XML parse.Production evidence (read-only, 2026-10-11)
systemctl cat/systemctl show:pensieve-api→releases/api-7ac5121/pensieve-serve(90-postgres-cutover.conf,PENSIEVE_POSTGRES_API_FAMILIES=none).pensieve-preview→releases/preview-3ab1045/pensieve-preview(10-release.conf).pensieve-ingest→/data/pensieve-build/negentropy-20f0b4b/release/pensieve-ingest(zzzz-bounded-canary.conf,Restart=no). The other three drop-ins aregiftwrap-recipient-block.conf,nip66-monitor.confandoverride.conf.ls:~/pensieve/releasesholdsapi-{6b21547,8a6bc61,9829378,7ac5121}andpreview-3ab1045.~/releasesholdsnegentropy-*source copies.~/pensieve/target/release/pensieve-previewis dated 2026-07-27.git -C ~/pensieve status:masterat 557d241, 29 behindorigin/master. Modified:env.production.example,ops/production/compose.yml,ops/scripts/sync-archive.sh. The editedsync-archive.shis identical to current master, and the other two differ from master only by later additions on master. Detached worktrees exist forgiftwrap-hotfix-5ecaca9,pensieve-canary-72da64e,pensieve-preview-3ab1045andpensieve-slice6-8d004f2./etc/pensieve/pensieve.env(names only):CLICKHOUSE_DB, notCLICKHOUSE_DATABASE(harmless: the binaries default tonostr).POSTGRES_ANALYTICS_PASSWORDandPREVIEW_COMPACT_LOOKUPSare present. NoRELAY_DB_PATH.docker psshows clickhouse, grafana, prometheus and caddy; postgres-analytics is not running.SHOW CREATE TABLE nostr.events_locallists noPROJECTION, andsystem.projection_partsis empty.system.mutationsshows DROP PROJECTIONevents_by_authoron 2026-06-13 (manual, no migration),events_by_timeon 2026-07-27 andevents_by_kindon 2026-10-11 16:54, allis_done=1./datais at 57%.ch-init+ch-migrate-all+ prepared 017 yields the same 43 tables and views as production, with identical DDL apart from the projections onevents_local.ch-initfails on a bare server untilnostrexists; the production compose creates it viaCLICKHOUSE_DB.Findings inventory (line numbers refer to
masterbefore this PR)Misleads an operator or agent
git pull+just build-releasein~/pensieve; roll back withgit checkout HEAD~1+ rebuildreleases/…or/data/pensieve-build/…via drop-ins; the checkout is stale and has live edits~/pensieve/target/release/ch-migrate-allruns "pending" migrations;ch-migrateis "safe to run multiple times"; 009 is the exampleTRUNCATEand backfillsevents_by_authordropped by handpensieve.envconfigures the native binaries including ingestinstall ops/systemd/*.service--setenv=INVENTORY_ONLY=1EnvironmentFileoverrides it, so the full campaign would run/usr/bin/env INVENTORY_ONLY=1manual-postgresprofile, not runningpreview-lookupsfrom the checkoutDATABASE_URL127.0.0.1:5432POSTGRES_ANALYTICS_PASSWORD--import-relays-csv--import-discovered-json--output--output-dirjust run-ingest -- --help--breaks clapanalytics-builddefault-run--bin pensieve-analyticsplan/validate/benchusage--allow-full-scanafter 018/stats/engagementdocumented as live;/stats/events"total"Descriptive drift
sync/.envis loaded only by serve and previewROCKSDB_PATH,SEGMENT_SIZE,STORAGE_BOX_HOST/USERandS3_PREFIXare read by nothing;RELAY_DB_PATHwas undocumentedCH_CONTAINER, clean-data--env-file; Caddy/.vip/Prometheus/users.xml/config.xmlcomments contradicted the config:3000; it is:8080Not changed (follow-ups)
events_by_author. Production dropped it by hand and no repo migration covers that. Whether fresh installs should keep it is a schema decision, so I only documented it.~/pensieve) needs reconciling withmasterdeliberately. Itscompose.ymllacks master'sarchive-alerts.ymlPrometheus mount, so those alert rules are probably not loaded in production.0.0.0.0:9090(compose).grafanauser can read every database.cache_policy_for_pathin pensieve-serve may never match the nested/api/v1paths.clean-datarecipe leaves./segmentsbehind.🤖 Generated with Claude Code