diff --git a/.env.example b/.env.example
index e6e861f685..9acbfb6e33 100644
--- a/.env.example
+++ b/.env.example
@@ -225,13 +225,13 @@ GITTENSORY_REVIEW_DRAFT=false
# # write trust can differ. Unrelated to ADMIN_GITHUB_LOGINS, which
# # scopes dashboard sign-in, not the shared MCP token's per-repo reach.
# PORT=8787
-# DATABASE_PATH=/data/gittensory.sqlite # SQLite file on the mounted data volume; all migrations auto-apply
+# DATABASE_PATH=/data/loopover.sqlite # SQLite file on the mounted data volume; all migrations auto-apply
# POSTGRES_PASSWORD=change-this-long-random-value # used by the --profile postgres / --profile pgbouncer services
# DATABASE_URL= # set to postgres://user:pw@host:5432/db to use Postgres instead of
# # SQLite (shared DB → multi-instance). Overrides DATABASE_PATH.
# # Compose examples:
-# # postgres://gittensory:@postgres:5432/gittensory
-# # postgres://gittensory:@pgbouncer:5432/gittensory
+# # postgres://loopover:@postgres:5432/loopover
+# # postgres://loopover:@pgbouncer:5432/loopover
# PGVECTOR_ENABLED=false # set true only when using the Postgres pgvector table for RAG.
# # Leave false when QDRANT_URL is set; Qdrant remains the preferred
# # dedicated vector store for review context at scale.
@@ -469,14 +469,14 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review
# RUNNER_REPO_URL=https://github.com/org/repo
# RUNNER_ACCESS_TOKEN= # PAT with repo scope (alternative to RUNNER_TOKEN)
# RUNNER_SCOPE=repo # repo | org | enterprise
-# RUNNER_NAME=gittensory-runner
+# RUNNER_NAME=loopover-runner
# RUNNER_LABELS=self-hosted,linux
# RUNNER_MEM_LIMIT=2g # per-runner-container memory ceiling; raise for memory-heavy CI jobs
# --- Docker disk hygiene (#audit-rate-headroom / #selfhost-runtime-pressure) ---
# Build cache and unused images accumulate fast on a box that builds from source or runs CI runners; a root
# disk over ~80-85% full slows down the WHOLE host (fsync latency, container scheduling), not just Docker.
-# Install the systemd timer (systemd/gittensory-docker-prune.{service,timer}.example) to reclaim stopped
+# Install the systemd timer (systemd/loopover-docker-prune.{service,timer}.example) to reclaim stopped
# containers, unused images, and build cache on a schedule -- never volumes/application data. Run it
# manually at any time with `sh scripts/selfhost-docker-prune.sh`, or preview first with `--dry-run`.
# GITTENSORY_DOCKER_PRUNE_RETAIN_HOURS=168 # age floor before something unused is eligible for pruning (7 days)
diff --git a/.env.selfhost.example b/.env.selfhost.example
index 2d8903f986..3690df5c7d 100644
--- a/.env.selfhost.example
+++ b/.env.selfhost.example
@@ -55,7 +55,7 @@ ADMIN_GITHUB_LOGINS=your-github-login
# SQLite is the default database (this file on the mounted data volume; migrations auto-apply).
# It's fine for a single maintainer instance. Move to Postgres (--profile postgres, see
# .env.example) once you're running multiple instances or a serious volume of repos.
-DATABASE_PATH=/data/gittensory.sqlite
+DATABASE_PATH=/data/loopover.sqlite
# Redis is REQUIRED and starts automatically with the default compose stack (webhook dedup, rate
# limiting, the GitHub GET-response cache). Only override this if you're pointing at an external
diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-ai-providers.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-ai-providers.tsx
index a9a5d5e5c8..99019fef33 100644
--- a/apps/gittensory-ui/src/routes/docs.self-hosting-ai-providers.tsx
+++ b/apps/gittensory-ui/src/routes/docs.self-hosting-ai-providers.tsx
@@ -185,7 +185,7 @@ CLAUDE_AI_EFFORT=medium`}
creation time, so a plain restart keeps serving the old value — recreate the service
instead:
-
+
Prefer not pasting the raw token into .env? Write it into{" "}
secrets/claude_code_oauth_token.txt instead (see{" "}
diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-backup-scaling.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-backup-scaling.tsx
index 3eff2db4d3..1026679e0b 100644
--- a/apps/gittensory-ui/src/routes/docs.self-hosting-backup-scaling.tsx
+++ b/apps/gittensory-ui/src/routes/docs.self-hosting-backup-scaling.tsx
@@ -55,7 +55,7 @@ LITESTREAM_REGION=us-east-1`}
Scheduled backups
The bundled backup profile writes the active app database to the{" "}
- gittensory-backups volume. SQLite installs use an online backup; Postgres
+ loopover-backups volume. SQLite installs use an online backup; Postgres
installs use pg_dump. The same run also snapshots Qdrant when it is enabled.
@@ -64,7 +64,7 @@ LITESTREAM_REGION=us-east-1`}
Each run keeps the newest BACKUP_RETAIN backups (default 7) —
applied independently per target: postgres/, sqlite/, and{" "}
- qdrant/ in the gittensory-backups volume each retain their own
+ qdrant/ in the loopover-backups volume each retain their own
newest 7, not 7 combined across all three. Set it in .env to change the window:
diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-docs-audit.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-docs-audit.tsx
index e6c24ca19f..4e6632911b 100644
--- a/apps/gittensory-ui/src/routes/docs.self-hosting-docs-audit.tsx
+++ b/apps/gittensory-ui/src/routes/docs.self-hosting-docs-audit.tsx
@@ -130,7 +130,7 @@ function SelfHostingDocsAudit() {
Operator-owned paths:gittensory-config/,{" "}
- gittensory-data, and secrets via .env or *_FILE{" "}
+ loopover-data, and secrets via .env or *_FILE{" "}
mounts — never baked into images.
diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx
index 9962358ef9..50ad3918c2 100644
--- a/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx
+++ b/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx
@@ -55,7 +55,7 @@ function SelfHostingOperations() {
@@ -406,7 +406,7 @@ DISCORD_REPO_WEBHOOKS={"owner/repoA":"https://discord.com/api/webhooks/...","own
expected steady state, not a leak — this instance runs{" "}
scripts/deploy-selfhost-prebuilt.sh, which rebuilds the image from the current
git checkout on every deploy and intentionally keeps prior layers around in the build cache
- for faster rebuilds. The gittensory-docker-safe-prune systemd timer (below)
+ for faster rebuilds. The loopover-docker-safe-prune systemd timer (below)
already runs daily against this exact instance and reclaims it on a schedule, so this is not
a number to chase down manually.
@@ -486,11 +486,11 @@ DISCORD_REPO_WEBHOOKS={"owner/repoA":"https://discord.com/api/webhooks/...","own
Run it manually at any time with docker system df before and after to see what
@@ -549,7 +549,7 @@ services:
condition: service_completed_successfully
environment:
<<: *runner-tmp-env
- RUNNER_NAME: gittensory-runner-2
+ RUNNER_NAME: loopover-runner-2
RUNNER_SCOPE: \${RUNNER_SCOPE:-repo}
REPO_URL: \${RUNNER_REPO_URL:-}
RUNNER_TOKEN: \${RUNNER_TOKEN:-}
@@ -581,7 +581,7 @@ SENTRY_RELEASE=gittensory-selfhost@2026.07.05
Official release images bake GITTENSORY_VERSION as the default release id;
override with SENTRY_RELEASE when you tag custom builds. Mount secrets with{" "}
SENTRY_DSN_FILE instead of inline env when you prefer a file-backed DSN. After
- changing Sentry env, restart the gittensory service — there is no hot reload.
+ changing Sentry env, restart the loopover service — there is no hot reload.
Community self-hosters should send events only to their own DSN. The shipped stack never
@@ -885,8 +885,8 @@ SENTRY_ORG_SLUG=
Updating and rolling back
- Day-two operator flow: pull or build a new app image, restart only the{" "}
- gittensory service, verify /ready, and confirm the release id. Use{" "}
+ Day-two operator flow: pull or build a new app image, restart only the loopover{" "}
+ service, verify /ready, and confirm the release id. Use{" "}
Releases and images to pick a tag; use the
checklists below so updates never overwrite operator-owned secrets, config, or data.
- Named data volumes — especially gittensory-data (SQLite DB, Codex/Claude
- auth under /data), gittensory-pg, qdrant-data,{" "}
- gittensory-backups, and Grafana's grafana-data.
+ Named data volumes — especially loopover-data (SQLite DB, Codex/Claude auth
+ under /data), loopover-pg, qdrant-data,{" "}
+ loopover-backups, and Grafana's grafana-data.
Image path only: note the current tag or digest from docker inspect on the
- running gittensory container so rollback has a known-good target.
+ running loopover container so rollback has a known-good target.
Confirm routine health is green before you start —{" "}
@@ -964,7 +964,7 @@ SENTRY_ORG_SLUG=
Path 1: pull a published image
scripts/deploy-selfhost-image.sh pulls a tag or digest, restarts only the{" "}
- gittensory service, waits for it to report healthy via{" "}
+ loopover service, waits for it to report healthy via{" "}
docker inspect's health status (configurable timeout, default 180s), and
then persists the resolved image reference back to GITTENSORY_IMAGE in{" "}
.env so the next plain invocation reuses it.
@@ -1036,7 +1036,7 @@ git merge --ff-only origin/main
scripts/deploy-selfhost-prebuilt.sh is the actual rebuild step (this is how{" "}
GITTENSORY_VERSION ends up as a short git SHA instead of an image tag). It
builds the bundle inside a Dockerized Node container — the host itself never needs Node or
- npm installed — then restarts only the gittensory service the same way as the
+ npm installed — then restarts only the loopover service the same way as the
image path. SENTRY_RELEASE defaults to{" "}
gittensory-selfhost@<short git SHA of the current HEAD> unless you
override it, so each deploy from a new commit gets a distinct release id automatically. When{" "}
@@ -1062,7 +1062,7 @@ git merge --ff-only origin/main
curl http://localhost:8787/ready returns HTTP 200.
If any check fails, see Troubleshooting
@@ -1147,8 +1147,8 @@ docker inspect --format '{{.Config.Image}}' "$(docker compose ps -q gittensory)"
Stopping the container does not delete anything — docker compose stop or{" "}
docker compose down (without -v) leaves every named volume (
- gittensory-data, gittensory-pg, qdrant-data,{" "}
- gittensory-backups, grafana-data, and the rest declared in{" "}
+ loopover-data, loopover-pg, qdrant-data,{" "}
+ loopover-backups, grafana-data, and the rest declared in{" "}
docker-compose.yml) on disk, along with the ./gittensory-config{" "}
host directory (a bind mount, not a named volume, so it is never affected by -v{" "}
either way). Pick one:
@@ -1168,7 +1168,7 @@ docker inspect --format '{{.Config.Image}}' "$(docker compose ps -q gittensory)"
{
title: "Delete everything",
description:
- "docker compose down -v removes every named volume permanently — the review database, vector index, Grafana dashboards state, and any local backup archives in gittensory-backups go with it. This does not touch ./gittensory-config (delete that host directory yourself if it should go too).",
+ "docker compose down -v removes every named volume permanently — the review database, vector index, Grafana dashboards state, and any local backup archives in loopover-backups go with it. This does not touch ./gittensory-config (delete that host directory yourself if it should go too).",
},
]}
/>
@@ -1215,13 +1215,13 @@ docker inspect --format '{{.Config.Image}}' "$(docker compose ps -q gittensory)"
request (isAuthorizedGitHubSessionLogin in src/auth/security.ts) —
it is never cached at startup or baked into an issued session. To remove someone's
operator access, delete their login from the comma/whitespace-separated list in{" "}
- .env and restart the gittensory service so the process picks up
- the new value:
+ .env and restart the loopover service so the process picks up the
+ new value:
This takes effect on their very next control-panel request after the restart — no signed-in
diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-security.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-security.tsx
index f721b91164..8df5692da9 100644
--- a/apps/gittensory-ui/src/routes/docs.self-hosting-security.tsx
+++ b/apps/gittensory-ui/src/routes/docs.self-hosting-security.tsx
@@ -67,7 +67,7 @@ function SelfHostingSecurity() {
filename="shell"
code={`./scripts/selfhost-init-secrets.sh # creates empty placeholder files (idempotent)
printf '%s' 'your-real-secret-value' > secrets/github_webhook_secret.txt
-docker compose up -d --no-deps gittensory`}
+docker compose up -d --no-deps loopover`}
/>
Private policy
diff --git a/caddy/Caddyfile b/caddy/Caddyfile
index 197bb96683..9feea41a46 100644
--- a/caddy/Caddyfile
+++ b/caddy/Caddyfile
@@ -1,15 +1,15 @@
-# Caddy reverse proxy for gittensory (#980 self-host).
+# Caddy reverse proxy for loopover (#980 self-host).
# Activated via: docker compose --profile caddy up
#
# DOMAIN is injected from the DOMAIN env var in docker-compose.yml.
# Set DOMAIN=reviews.yourcompany.com in .env — Caddy fetches a TLS cert from Let's Encrypt automatically.
# For local testing without a domain, set DOMAIN=localhost (self-signed cert, browser will warn).
#
-# When using this profile, remove the `ports:` entry from the gittensory service in docker-compose.yml
+# When using this profile, remove the `ports:` entry from the loopover service in docker-compose.yml
# so port 8787 is NOT exposed publicly — all traffic should flow through Caddy on 443.
{$DOMAIN} {
- reverse_proxy gittensory:8787 {
+ reverse_proxy loopover:8787 {
# Surface the real client IP to the app (logged in access events).
header_up X-Forwarded-For {remote_host}
header_up X-Real-IP {remote_host}
diff --git a/docker-compose.override.yml.example b/docker-compose.override.yml.example
index 96b5605f1d..ced8e187b6 100644
--- a/docker-compose.override.yml.example
+++ b/docker-compose.override.yml.example
@@ -1,10 +1,10 @@
-# Optional CPU-priority tuning for boxes running `--profile runners` alongside the main `gittensory`
+# Optional CPU-priority tuning for boxes running `--profile runners` alongside the main `loopover`
# app on the SAME host. Copy to `docker-compose.override.yml` (gitignored, auto-loaded by `docker
# compose` alongside docker-compose.yml) and adjust the numbers for your host if you use this pattern.
#
# WHY THIS EXISTS: with no limits set (the default -- see docker-compose.yml), every container competes
# for the host's CPUs on equal footing. On a box that ALSO runs `--profile runners`, a burst of CI jobs
-# can starve the `gittensory` app itself of CPU, slowing down (or queuing up) the very review work the
+# can starve the `loopover` app itself of CPU, slowing down (or queuing up) the very review work the
# app exists to do -- discovered running this exact pattern in production on an 8-vCPU box: 3 uncapped
# runner containers left the app starved under load.
#
@@ -21,16 +21,16 @@
# scheduler (driven by the relative `cpu_shares` below) resolves real contention when multiple containers
# actually want the CPU at once.
#
-# Sizing guide for a different host: pick a `gittensory` : `runner` cpu_shares ratio reflecting how
+# Sizing guide for a different host: pick a `loopover` : `runner` cpu_shares ratio reflecting how
# strongly you want review work to win contention (8:1 below is deliberately aggressive), and keep each
# runner replica's `cpus` ceiling at roughly (host vCPUs) / (number of runner replicas you plan to run),
# so a single busy runner can't monopolize the box even before shares kick in.
#
# This is the HOST-level (Docker CPU scheduling) half of the fix. The APPLICATION-level half is the
-# MAINTENANCE_ADMISSION_* knobs in .env.example: gittensory itself defers its own maintenance sweeps
+# MAINTENANCE_ADMISSION_* knobs in .env.example: loopover itself defers its own maintenance sweeps
# (contributor evidence, RAG indexing, drift scans...) under queue/host pressure so live webhook/review
# work always wins there too. Also see ./scripts/selfhost-docker-prune.sh (and its systemd timer under
-# systemd/gittensory-docker-prune.*.example) for the disk-usage side of running CI builds on the same box
+# systemd/loopover-docker-prune.*.example) for the disk-usage side of running CI builds on the same box
# (build cache/image growth, not just CPU).
# The RECOMMENDED alternative to all of this: don't co-locate runners with the review stack at all -- use
# GitHub-hosted CI, or a separate dedicated runner host (see the runner service's comment in
@@ -47,7 +47,7 @@
# operations docs for a complete, copy-pasteable multi-runner service snippet.
services:
- gittensory:
+ loopover:
cpu_shares: 4096
runner:
diff --git a/docker-compose.yml b/docker-compose.yml
index b8999ed90e..77d1994363 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,4 +1,4 @@
-# Self-host for gittensory (#980). Two ways to boot the `gittensory` service — everything else in
+# Self-host for loopover (#980). Two ways to boot the `loopover` service — everything else in
# this compose file (profiles, env, health checks) is identical either way:
#
# RECOMMENDED: ./scripts/deploy-selfhost-image.sh # pulls the published image, no local build
@@ -72,7 +72,7 @@ x-runner-tmp-env: &runner-tmp-env
services:
# ── Core app (always runs) ─────────────────────────────────────────────────
- gittensory:
+ loopover:
build:
context: .
args:
@@ -88,7 +88,7 @@ services:
required: false
environment:
PORT: "8787"
- DATABASE_PATH: /data/gittensory.sqlite
+ DATABASE_PATH: /data/loopover.sqlite
# Container-private per-repo config (#1390): point at a mounted dir holding {owner}__{repo}/.gittensory.yml
# files layered over an optional root .gittensory.yml global default, itself layered over an optional
# _shared/.gittensory.yml cross-repo base for multi-repo operators (#1959) — a higher layer overrides only the
@@ -108,10 +108,10 @@ services:
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE: "${OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE:-cumulative}"
OTEL_METRIC_EXPORT_INTERVAL: "${OTEL_METRIC_EXPORT_INTERVAL:-10000}"
# Uncomment the next two lines and activate --profile postgres to use Postgres:
- # DATABASE_URL: postgres://gittensory:${POSTGRES_PASSWORD:-CHANGEME}@postgres:5432/gittensory
+ # DATABASE_URL: postgres://loopover:${POSTGRES_PASSWORD:-CHANGEME}@postgres:5432/loopover
# PGVECTOR_ENABLED: "true"
# With --profile pgbouncer, route through the pooler instead of postgres directly:
- # DATABASE_URL: postgres://gittensory:${POSTGRES_PASSWORD:-CHANGEME}@pgbouncer:5432/gittensory
+ # DATABASE_URL: postgres://loopover:${POSTGRES_PASSWORD:-CHANGEME}@pgbouncer:5432/loopover
# Required shared transient state for review correctness, webhook dedup, and rate limiting.
REDIS_URL: "${REDIS_URL:-redis://redis:6379}"
# Enables the GitHub GET-response cache when >0 (0 disables); not a per-entry TTL, see .env.example.
@@ -122,8 +122,8 @@ services:
# additive, zero effect on an operator who has never touched secrets/.
GITHUB_APP_PRIVATE_KEY_FILE: "${GITHUB_APP_PRIVATE_KEY_FILE:-/run/secrets/github_app_private_key}"
GITHUB_WEBHOOK_SECRET_FILE: "${GITHUB_WEBHOOK_SECRET_FILE:-/run/secrets/github_webhook_secret}"
- GITTENSORY_API_TOKEN_FILE: "${GITTENSORY_API_TOKEN_FILE:-/run/secrets/gittensory_api_token}"
- GITTENSORY_MCP_TOKEN_FILE: "${GITTENSORY_MCP_TOKEN_FILE:-/run/secrets/gittensory_mcp_token}"
+ GITTENSORY_API_TOKEN_FILE: "${GITTENSORY_API_TOKEN_FILE:-/run/secrets/loopover_api_token}"
+ GITTENSORY_MCP_TOKEN_FILE: "${GITTENSORY_MCP_TOKEN_FILE:-/run/secrets/loopover_mcp_token}"
INTERNAL_JOB_TOKEN_FILE: "${INTERNAL_JOB_TOKEN_FILE:-/run/secrets/internal_job_token}"
SELFHOST_SETUP_TOKEN_FILE: "${SELFHOST_SETUP_TOKEN_FILE:-/run/secrets/selfhost_setup_token}"
TOKEN_ENCRYPTION_SECRET_FILE: "${TOKEN_ENCRYPTION_SECRET_FILE:-/run/secrets/token_encryption_secret}"
@@ -141,7 +141,7 @@ services:
# short-lived GitHub tokens from the Orb on demand (no own App private key). See .env.example.
# ORB_BROKER_URL: https://gittensory-api.aethereal.dev # override only for a private Orb deployment
volumes:
- - gittensory-data:/data
+ - loopover-data:/data
# Container-private per-repo config dir (read-only). Create ./gittensory-config/{owner}__{repo}/.gittensory.yml
# locally, optionally alongside a ./gittensory-config/.gittensory.yml global default that every per-repo file
# is deep-merged over (gitignored — never commit real policy; see config/examples/ for generic templates).
@@ -162,8 +162,8 @@ services:
secrets:
- github_app_private_key
- github_webhook_secret
- - gittensory_api_token
- - gittensory_mcp_token
+ - loopover_api_token
+ - loopover_mcp_token
- internal_job_token
- selfhost_setup_token
- token_encryption_secret
@@ -180,7 +180,7 @@ services:
qdrant:
condition: service_healthy
required: false
- # Same pattern for --profile postgres / --profile pgbouncer: without this, compose starts gittensory
+ # Same pattern for --profile postgres / --profile pgbouncer: without this, compose starts loopover
# in parallel with a cold Postgres initdb instead of waiting for it, and the app's own waitForPostgres()
# fallback (~30s hard cap) commonly loses that race on a slow disk/first pull, crash-looping the app via
# restart: unless-stopped before Postgres is reachable. required:false keeps the default SQLite path
@@ -282,11 +282,11 @@ services:
<<: *default-logging
profiles: ["postgres", "pgbouncer"]
environment:
- POSTGRES_USER: gittensory
+ POSTGRES_USER: loopover
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-CHANGEME}
- POSTGRES_DB: gittensory
+ POSTGRES_DB: loopover
volumes:
- - gittensory-pg:/var/lib/postgresql/data
+ - loopover-pg:/var/lib/postgresql/data
deploy:
resources:
limits:
@@ -296,7 +296,7 @@ services:
# the pgvector extension) can plausibly take longer than the 5x10s=50s this healthcheck otherwise
# allows before Docker marks the service unhealthy and fails every downstream service_healthy gate.
healthcheck:
- test: ["CMD-SHELL", "pg_isready -U gittensory"]
+ test: ["CMD-SHELL", "pg_isready -U loopover"]
interval: 10s
timeout: 5s
start_period: 20s
@@ -304,7 +304,7 @@ services:
# ── PgBouncer (--profile pgbouncer) ───────────────────────────────────────
# Transaction-mode pooler — allows hundreds of app clients with a small PG connection cap.
- # Set DATABASE_URL in gittensory to: postgres://gittensory:@pgbouncer:5432/gittensory
+ # Set DATABASE_URL in loopover to: postgres://loopover:@pgbouncer:5432/loopover
pgbouncer:
image: edoburu/pgbouncer:v1.25.2-p0
restart: unless-stopped
@@ -316,8 +316,8 @@ services:
environment:
DB_HOST: postgres
DB_PORT: "5432"
- DB_NAME: gittensory
- DB_USER: gittensory
+ DB_NAME: loopover
+ DB_USER: loopover
DB_PASSWORD: ${POSTGRES_PASSWORD:-CHANGEME}
LISTEN_PORT: "5432"
POOL_MODE: transaction
@@ -327,7 +327,7 @@ services:
# The image ships the full postgresql-client toolchain (Alpine-based), so the same probe postgres itself
# uses works here: pg_isready only checks that the server accepts the startup packet, not that auth
# succeeds, so it reports "accepting connections" even before the upstream Postgres is reachable through
- # the pooler — exactly the pooler-layer liveness signal gittensory's depends_on needs.
+ # the pooler — exactly the pooler-layer liveness signal loopover's depends_on needs.
healthcheck:
test: ["CMD", "pg_isready", "-h", "127.0.0.1", "-p", "5432"]
interval: 10s
@@ -346,8 +346,8 @@ services:
postgres:
condition: service_healthy
environment:
- DATA_SOURCE_URI: "postgres:5432/gittensory?sslmode=disable"
- DATA_SOURCE_USER: gittensory
+ DATA_SOURCE_URI: "postgres:5432/loopover?sslmode=disable"
+ DATA_SOURCE_USER: loopover
DATA_SOURCE_PASS: ${POSTGRES_PASSWORD:-CHANGEME}
expose:
- "9187"
@@ -602,7 +602,7 @@ services:
restart: unless-stopped
<<: *default-logging
profiles: ["rees"]
- # Deliberately NOT `env_file: .env` like the gittensory service above: that would also hand this
+ # Deliberately NOT `env_file: .env` like the loopover service above: that would also hand this
# analyzer service every unrelated secret in .env, and REES reads the same SENTRY_DSN key name the main
# app uses (src/selfhost/sentry.ts) -- blanket-forwarding .env would silently point REES's error reporting
# at the main app's Sentry project instead of a dedicated one. Add REES-specific Sentry vars via
@@ -623,7 +623,7 @@ services:
limits:
memory: "${REES_MEM_LIMIT:-512m}"
# /health and /ready are both unconditional no-ops (REES has no DB/queue to probe), so unlike the
- # gittensory service above there's no deeper readiness signal to prefer here; /health also matches
+ # loopover service above there's no deeper readiness signal to prefer here; /health also matches
# Railway's own healthcheckPath for this service. `node -e fetch(...)` avoids assuming curl/wget exist --
# review-enrichment/Dockerfile's runtime stage is node:22-slim, which installs neither.
healthcheck:
@@ -649,10 +649,10 @@ services:
profiles: ["litestream"]
command: replicate
depends_on:
- gittensory:
+ loopover:
condition: service_healthy
volumes:
- - gittensory-data:/data
+ - loopover-data:/data
- ./litestream.yml:/etc/litestream.yml:ro
environment:
LITESTREAM_ACCESS_KEY_ID: ${LITESTREAM_ACCESS_KEY_ID:-}
@@ -662,7 +662,7 @@ services:
# ── Caddy (--profile caddy) ────────────────────────────────────────────────
# Auto-TLS via Let's Encrypt. Set DOMAIN=reviews.yourcompany.com in .env, then
- # remove the plain `ports:` entry from the gittensory service above.
+ # remove the plain `ports:` entry from the loopover service above.
caddy:
image: caddy:2-alpine
restart: unless-stopped
@@ -679,7 +679,7 @@ services:
environment:
DOMAIN: ${DOMAIN:-localhost}
depends_on:
- gittensory:
+ loopover:
condition: service_healthy
# ── Observability (--profile observability) ────────────────────────────────
@@ -787,11 +787,11 @@ services:
<<: *default-logging
profiles: ["observability"]
depends_on:
- gittensory:
+ loopover:
condition: service_healthy
volumes:
# The exporter needs live DB read access to build the redacted snapshot. Grafana does not get this mount.
- - gittensory-data:/appdb:ro
+ - loopover-data:/appdb:ro
- grafana-reporting-data:/reporting
# A DIRECTORY bind mount, not a single-file one (#reporting-exporter-stale-bind-mount): a single-file
# bind mount pins the container to the file's INODE at container-creation time. `git pull` replaces a
@@ -803,15 +803,15 @@ services:
# provisioning below already does.
- ./scripts:/scripts:ro
environment:
- # Default SQLite app DB path maps app /data/gittensory.sqlite to exporter /appdb/gittensory.sqlite.
+ # Default SQLite app DB path maps app /data/loopover.sqlite to exporter /appdb/loopover.sqlite.
# If you override DATABASE_PATH, set this to the matching /appdb/ path. When DATABASE_URL points at
# Postgres, the exporter reads Postgres with psql and still writes the same redacted SQLite reporting DB
# for Grafana. Set GITTENSORY_REPORTING_SOURCE_DATABASE_URL only if the reporting reader uses a different URL.
- GITTENSORY_REPORTING_SOURCE_DB: "${GITTENSORY_REPORTING_SOURCE_DB:-/appdb/gittensory.sqlite}"
+ GITTENSORY_REPORTING_SOURCE_DB: "${GITTENSORY_REPORTING_SOURCE_DB:-/appdb/loopover.sqlite}"
GITTENSORY_REPORTING_SOURCE_DATABASE_URL: "${GITTENSORY_REPORTING_SOURCE_DATABASE_URL:-}"
DATABASE_URL: "${DATABASE_URL:-}"
GITTENSORY_REPORTING_DIR: /reporting
- GITTENSORY_REPORTING_DB: "${GITTENSORY_REPORTING_DB:-/reporting/gittensory-reporting.sqlite}"
+ GITTENSORY_REPORTING_DB: "${GITTENSORY_REPORTING_DB:-/reporting/loopover-reporting.sqlite}"
GRAFANA_REPORTING_EXPORT_INTERVAL_SECONDS: "${GRAFANA_REPORTING_EXPORT_INTERVAL_SECONDS:-30}"
command:
- /bin/sh
@@ -828,7 +828,7 @@ services:
test:
[
"CMD-SHELL",
- "db=\"$${GITTENSORY_REPORTING_DB:-/reporting/gittensory-reporting.sqlite}\"; test -s \"$$db\" && sqlite3 \"$$db\" 'PRAGMA quick_check;' | grep -q '^ok$'",
+ "db=\"$${GITTENSORY_REPORTING_DB:-/reporting/loopover-reporting.sqlite}\"; test -s \"$$db\" && sqlite3 \"$$db\" 'PRAGMA quick_check;' | grep -q '^ok$'",
]
interval: 30s
timeout: 5s
@@ -888,7 +888,7 @@ services:
# ── Log pipeline (--profile observability) ─────────────────────────────────
# Loki stores logs; Promtail discovers every container in this compose project via the read-only
# docker-proxy (NOT a raw socket) and ships their logs to Loki. Browse in Grafana → Explore →
- # Loki, e.g. {service="gittensory"} | json | level="error".
+ # Loki, e.g. {service="loopover"} | json | level="error".
loki:
image: grafana/loki:3.7.3
restart: unless-stopped
@@ -947,7 +947,7 @@ services:
depends_on: [loki, docker-proxy]
environment:
# Promtail expands this into its Docker label filter so discovery stays inside this Compose project.
- COMPOSE_PROJECT_NAME: ${COMPOSE_PROJECT_NAME:-gittensory}
+ COMPOSE_PROJECT_NAME: ${COMPOSE_PROJECT_NAME:-loopover}
volumes:
- ./promtail/promtail-config.yml:/etc/promtail/promtail-config.yml:ro
# Persist read positions so restarts don't re-ship the whole log history.
@@ -1007,7 +1007,7 @@ services:
# ── Tailscale (--profile tailscale) ───────────────────────────────────────
# Joins your tailnet so the stack is accessible via Tailscale IP/hostname — no
# public ports exposed. Generate an auth key at tailscale.com/settings/keys and
- # set TS_AUTHKEY= in .env. The gittensory service is reachable at the tailnet IP on port 8787.
+ # set TS_AUTHKEY= in .env. The loopover service is reachable at the tailnet IP on port 8787.
tailscale:
# Kept on the `stable` release channel rather than a version tag: tailscale's ghcr tags use a
# non-obvious scheme and the client is happiest tracking the current stable. For a fully immutable
@@ -1017,7 +1017,7 @@ services:
restart: unless-stopped
<<: *default-logging
profiles: ["tailscale"]
- hostname: gittensory
+ hostname: loopover
cap_add:
- NET_ADMIN
- SYS_MODULE
@@ -1037,7 +1037,7 @@ services:
# Runs `runs-on: self-hosted` jobs on this machine. Set RUNNER_TOKEN= (or ACCESS_TOKEN=)
# and RUNNER_REPO_URL= (e.g. https://github.com/your-org/your-repo) in .env.
# Get a token at: https://github.com///settings/actions/runners/new
- # Running this alongside the main `gittensory` app on the SAME host? A burst of CI jobs can starve the
+ # Running this alongside the main `loopover` app on the SAME host? A burst of CI jobs can starve the
# app of CPU with no limits set (the default below) -- confirmed in production: 3 uncapped runner
# containers on an 8-vCPU box left the app starved under load. See docker-compose.override.yml.example
# for a proven CPU-priority pattern (relative cpu_shares + a per-container cpus ceiling) before scaling
@@ -1072,7 +1072,7 @@ services:
REPO_URL: ${RUNNER_REPO_URL:-}
RUNNER_TOKEN: ${RUNNER_TOKEN:-}
ACCESS_TOKEN: ${RUNNER_ACCESS_TOKEN:-}
- RUNNER_NAME: ${RUNNER_NAME:-gittensory-runner}
+ RUNNER_NAME: ${RUNNER_NAME:-loopover-runner}
LABELS: ${RUNNER_LABELS:-self-hosted,linux,x64}
RUNNER_WORKDIR: /tmp/runner
# Docker builds are disabled by default. To enable DinD (Docker-in-Docker) for workflows that
@@ -1092,7 +1092,7 @@ services:
# ── Backups (--profile backup) ────────────────────────────────────────────
# Active database backup (Postgres pg_dump or WAL-safe SQLite online backup) + a Qdrant snapshot, on a loop
- # (default daily), kept in the gittensory-backups volume with retention. Run on demand:
+ # (default daily), kept in the loopover-backups volume with retention. Run on demand:
# docker compose --profile backup run --rm backup sh /scripts/backup.sh
# Verify the newest backup is restorable (pg_restore --list / SQLite integrity_check; opt-in scratch restore):
# docker compose --profile backup run --rm backup sh /scripts/verify-backup.sh
@@ -1102,7 +1102,7 @@ services:
<<: *default-logging
profiles: ["backup"]
environment:
- DATABASE_PATH: /data/gittensory.sqlite
+ DATABASE_PATH: /data/loopover.sqlite
DATABASE_URL: "${DATABASE_URL:-}"
GITTENSORY_BACKUP_SOURCE_DATABASE_URL: "${GITTENSORY_BACKUP_SOURCE_DATABASE_URL:-}"
QDRANT_URL: ${QDRANT_URL:-http://qdrant:6333}
@@ -1113,8 +1113,8 @@ services:
GITTENSORY_VERIFY_SCRATCH_DATABASE_URL: "${GITTENSORY_VERIFY_SCRATCH_DATABASE_URL:-}"
volumes:
# RW (not :ro) so SQLite's online-backup can use the WAL index; the script only ever reads the DB.
- - gittensory-data:/data
- - gittensory-backups:/backups
+ - loopover-data:/data
+ - loopover-backups:/backups
# A DIRECTORY bind mount, not individual-file mounts (#reporting-exporter-stale-bind-mount): a
# single-file bind mount pins the container to that file's INODE at container-creation time, so a
# later `git pull` (which replaces a file via write-new-then-rename, not an in-place edit) leaves the
@@ -1149,7 +1149,7 @@ services:
<<: *default-logging
profiles: ["backup"]
volumes:
- - gittensory-backups:/backups:ro
+ - loopover-backups:/backups:ro
# Directory mount, not a single-file one -- same #reporting-exporter-stale-bind-mount rationale as
# the backup service above.
- ./scripts:/scripts:ro
@@ -1167,20 +1167,20 @@ services:
# Native Docker Compose secrets: file-mounted (at /run/secrets/), never
# exposed via `docker inspect`/`docker compose config` the way a plain `environment:`/`env_file` value is.
# Read by the app's existing generic _FILE loader (src/selfhost/load-file-secrets.ts) via the
-# `environment:` defaults set below on the gittensory service. Every file here is created empty (a no-op --
+# `environment:` defaults set below on the loopover service. Every file here is created empty (a no-op --
# an inline .env value always wins, see secrets/README.md) by `scripts/selfhost-init-secrets.sh`, which
# every deploy runs before `docker compose build/up` so a missing file source can never break a deploy for
-# an operator who has not opted into this convention. Scoped to the always-on gittensory service's own
+# an operator who has not opted into this convention. Scoped to the always-on loopover service's own
# highest-value secrets for now -- the same convention extends to any other service the same way.
secrets:
github_app_private_key:
file: ./secrets/github_app_private_key.pem
github_webhook_secret:
file: ./secrets/github_webhook_secret.txt
- gittensory_api_token:
- file: ./secrets/gittensory_api_token.txt
- gittensory_mcp_token:
- file: ./secrets/gittensory_mcp_token.txt
+ loopover_api_token:
+ file: ./secrets/loopover_api_token.txt
+ loopover_mcp_token:
+ file: ./secrets/loopover_mcp_token.txt
internal_job_token:
file: ./secrets/internal_job_token.txt
selfhost_setup_token:
@@ -1197,8 +1197,8 @@ secrets:
file: ./secrets/claude_code_oauth_token.txt
volumes:
- gittensory-data:
- gittensory-pg:
+ loopover-data:
+ loopover-pg:
qdrant-data:
ollama-models:
caddy-data:
@@ -1211,7 +1211,7 @@ volumes:
promtail-data:
tailscale-state:
runner-work:
- gittensory-backups:
+ loopover-backups:
tempo-data:
networks:
diff --git a/grafana/dashboards/gittensory.json b/grafana/dashboards/gittensory.json
index 1ccd1ab91c..d0dc0964ff 100644
--- a/grafana/dashboards/gittensory.json
+++ b/grafana/dashboards/gittensory.json
@@ -1452,7 +1452,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "sum(pg_stat_activity_count{datname=\"gittensory\"}) or vector(0)",
+ "expr": "sum(pg_stat_activity_count{datname=\"loopover\"}) or vector(0)",
"legendFormat": "connections",
"refId": "A"
}
@@ -1500,7 +1500,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "pg_database_size_bytes{datname=\"gittensory\"} or vector(0)",
+ "expr": "pg_database_size_bytes{datname=\"loopover\"} or vector(0)",
"legendFormat": "size",
"refId": "A"
}
@@ -1599,7 +1599,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "sum by (state) (pg_stat_activity_count{datname=\"gittensory\"}) or vector(0)",
+ "expr": "sum by (state) (pg_stat_activity_count{datname=\"loopover\"}) or vector(0)",
"legendFormat": "{{state}}",
"refId": "A"
}
@@ -1646,7 +1646,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "sum(pg_stat_activity_count{datname=\"gittensory\", wait_event_type=\"Lock\"}) or vector(0)",
+ "expr": "sum(pg_stat_activity_count{datname=\"loopover\", wait_event_type=\"Lock\"}) or vector(0)",
"legendFormat": "lock waits",
"refId": "A"
},
@@ -1655,7 +1655,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "max(pg_stat_activity_max_tx_duration{datname=\"gittensory\"}) or vector(0)",
+ "expr": "max(pg_stat_activity_max_tx_duration{datname=\"loopover\"}) or vector(0)",
"legendFormat": "max transaction seconds",
"refId": "B"
},
@@ -1664,7 +1664,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "rate(pg_stat_database_deadlocks{datname=\"gittensory\"}[5m]) or vector(0)",
+ "expr": "rate(pg_stat_database_deadlocks{datname=\"loopover\"}[5m]) or vector(0)",
"legendFormat": "deadlocks/s",
"refId": "C"
}
@@ -1711,7 +1711,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "pg_database_size_bytes{datname=\"gittensory\"} or vector(0)",
+ "expr": "pg_database_size_bytes{datname=\"loopover\"} or vector(0)",
"legendFormat": "database bytes",
"refId": "A"
},
@@ -1720,7 +1720,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "topk(10, pg_stat_user_tables_n_live_tup{datname=\"gittensory\"}) or vector(0)",
+ "expr": "topk(10, pg_stat_user_tables_n_live_tup{datname=\"loopover\"}) or vector(0)",
"legendFormat": "{{relname}} live rows",
"refId": "B"
}
@@ -1767,7 +1767,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "topk(10, pg_stat_user_tables_n_dead_tup{datname=\"gittensory\"}) or vector(0)",
+ "expr": "topk(10, pg_stat_user_tables_n_dead_tup{datname=\"loopover\"}) or vector(0)",
"legendFormat": "{{relname}} dead rows",
"refId": "A"
},
@@ -1776,7 +1776,7 @@
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "expr": "sum by (relname) (increase(pg_stat_user_tables_autovacuum_count{datname=\"gittensory\"}[1h])) or vector(0)",
+ "expr": "sum by (relname) (increase(pg_stat_user_tables_autovacuum_count{datname=\"loopover\"}[1h])) or vector(0)",
"legendFormat": "{{relname}} autovacuum/hour",
"refId": "B"
}
diff --git a/grafana/dashboards/resource-hub.json b/grafana/dashboards/resource-hub.json
index 8448daaa73..5822d043c7 100644
--- a/grafana/dashboards/resource-hub.json
+++ b/grafana/dashboards/resource-hub.json
@@ -55,7 +55,7 @@
"gridPos": { "h": 13, "w": 12, "x": 0, "y": 0 },
"options": {
"mode": "markdown",
- "content": "## 🧠 AI providers\n- **Claude Code / Codex** — subscription CLIs, the review brain. Health: app boot log `selfhost_ai_provider`.\n- **Ollama** — embeddings (`bge-m3`) for RAG · [API root](http://localhost:11434) · `docker exec gittensory-ollama-1 ollama list`\n\n## 🔎 Vector store (RAG)\n- **Qdrant** — [Dashboard](http://localhost:6333/dashboard) · [Collections API](http://localhost:6333/collections)\n- Embeddings indexed per repo; see the *RAG indexing* doc.\n\n## ⚙️ Engine / API\n- **gittensory app** — [/ ](http://localhost:8787/) · [/ready](http://localhost:8787/ready) · [/metrics](http://localhost:8787/metrics)\n- Internal jobs: `POST /v1/internal/jobs/rag-index` (bearer `INTERNAL_JOB_TOKEN`)\n\n## 💾 Data\n- **SQLite** (default) at `/data/gittensory.sqlite` — private to the app/exporter. Grafana reads `/reporting/gittensory-reporting.sqlite`, a redacted reporting snapshot.\n- **Postgres/pgvector** (optional `--profile postgres`).\n\n> Links assume the default published ports on the Docker host. If you run Grafana on a remote host, replace `localhost` with that host, and publish the service `ports:` you want to reach."
+ "content": "## 🧠 AI providers\n- **Claude Code / Codex** — subscription CLIs, the review brain. Health: app boot log `selfhost_ai_provider`.\n- **Ollama** — embeddings (`bge-m3`) for RAG · [API root](http://localhost:11434) · `docker exec loopover-ollama-1 ollama list`\n\n## 🔎 Vector store (RAG)\n- **Qdrant** — [Dashboard](http://localhost:6333/dashboard) · [Collections API](http://localhost:6333/collections)\n- Embeddings indexed per repo; see the *RAG indexing* doc.\n\n## ⚙️ Engine / API\n- **gittensory app** — [/ ](http://localhost:8787/) · [/ready](http://localhost:8787/ready) · [/metrics](http://localhost:8787/metrics)\n- Internal jobs: `POST /v1/internal/jobs/rag-index` (bearer `INTERNAL_JOB_TOKEN`)\n\n## 💾 Data\n- **SQLite** (default) at `/data/loopover.sqlite` — private to the app/exporter. Grafana reads `/reporting/loopover-reporting.sqlite`, a redacted reporting snapshot.\n- **Postgres/pgvector** (optional `--profile postgres`).\n\n> Links assume the default published ports on the Docker host. If you run Grafana on a remote host, replace `localhost` with that host, and publish the service `ports:` you want to reach."
}
},
diff --git a/grafana/provisioning/datasources/ams-ledgers.yml b/grafana/provisioning/datasources/ams-ledgers.yml
index bd98513ca5..313c368941 100644
--- a/grafana/provisioning/datasources/ams-ledgers.yml
+++ b/grafana/provisioning/datasources/ams-ledgers.yml
@@ -3,7 +3,7 @@
# Grafana must not mount the miner's live GITTENSORY_MINER_CONFIG_DIR ledgers. The attempt log and prediction
# ledger contain free-form reasons, payload JSON, repo/target identifiers, readiness scores, and blocker/warning
# codes that are private AMS intelligence. Instead, expose only redacted reporting-export snapshots, mirroring the
-# maintainer GittensoryDB pattern in sqlite.yml.
+# maintainer LoopoverDB pattern in sqlite.yml.
#
# PATH — the absolute path varies per install, so `path:` below is a documented placeholder. Publish sanitized AMS
# reporting exports into Grafana's existing reporting mount (for example /reporting/ams-attempt-log.sqlite and
diff --git a/grafana/provisioning/datasources/sqlite.yml b/grafana/provisioning/datasources/sqlite.yml
index ce2e7c8fc2..701127e3ad 100644
--- a/grafana/provisioning/datasources/sqlite.yml
+++ b/grafana/provisioning/datasources/sqlite.yml
@@ -2,10 +2,10 @@
# database produced by reporting-exporter; it never mounts the live application database.
apiVersion: 1
datasources:
- - name: GittensoryDB
+ - name: LoopoverDB
type: frser-sqlite-datasource
uid: gittensory-db
access: proxy
editable: false
jsonData:
- path: /reporting/gittensory-reporting.sqlite
+ path: /reporting/loopover-reporting.sqlite
diff --git a/litestream.yml.example b/litestream.yml.example
index dc4ae68b0c..fc52cb6609 100644
--- a/litestream.yml.example
+++ b/litestream.yml.example
@@ -1,13 +1,13 @@
# Litestream continuous-backup config for the self-host SQLite DB (SAMPLE — placeholders only).
-# Streams /data/gittensory.sqlite to your object store so you can restore to any point in time.
+# Streams /data/loopover.sqlite to your object store so you can restore to any point in time.
# Copy to litestream.yml, edit the bucket/endpoint, and mount it at /etc/litestream.yml (see docker-compose.yml).
# Docs: https://litestream.io
dbs:
- - path: /data/gittensory.sqlite
+ - path: /data/loopover.sqlite
replicas:
- type: s3
bucket: your-backup-bucket
- path: gittensory
+ path: loopover
# For S3-compatible stores (Backblaze B2, MinIO, R2) set the endpoint; omit it for AWS S3.
endpoint: ${LITESTREAM_ENDPOINT}
region: ${LITESTREAM_REGION}
diff --git a/packages/gittensory-miner/DEPLOYMENT.md b/packages/gittensory-miner/DEPLOYMENT.md
index 2fc2aa9881..d2850a3d25 100644
--- a/packages/gittensory-miner/DEPLOYMENT.md
+++ b/packages/gittensory-miner/DEPLOYMENT.md
@@ -100,7 +100,7 @@ sudo systemctl daemon-reload
sudo systemctl enable --now gittensory-miner.service
```
-Because `loop` is a **long-running daemon that schedules its own cycles**, it is a persistent `Type=simple` service (with `Restart=on-failure`) — **not** a oneshot unit driven by a `.timer`, unlike the periodic `gittensory-docker-prune.*.example` hygiene job in [`systemd/`](../../systemd/). Keep `GITHUB_TOKEN` (and any coding-agent credentials) in a root-owned `0600` `EnvironmentFile`, never in the unit file. Follow the loop with `journalctl -u gittensory-miner -f`; `systemctl stop` sends SIGTERM, which the loop handles cleanly at its next kill-switch check.
+Because `loop` is a **long-running daemon that schedules its own cycles**, it is a persistent `Type=simple` service (with `Restart=on-failure`) — **not** a oneshot unit driven by a `.timer`, unlike the periodic `loopover-docker-prune.*.example` hygiene job in [`systemd/`](../../systemd/). Keep `GITHUB_TOKEN` (and any coding-agent credentials) in a root-owned `0600` `EnvironmentFile`, never in the unit file. Follow the loop with `journalctl -u gittensory-miner -f`; `systemctl stop` sends SIGTERM, which the loop handles cleanly at its next kill-switch check.
## Invariants
diff --git a/packages/gittensory-miner/docs/observability.md b/packages/gittensory-miner/docs/observability.md
index 11f3732693..ad23a1f64d 100644
--- a/packages/gittensory-miner/docs/observability.md
+++ b/packages/gittensory-miner/docs/observability.md
@@ -26,7 +26,7 @@ The repo ships datasource provisioning at
`AMS Prediction Ledger` (uid `ams-prediction-ledger`). Their default paths live under Grafana's reporting mount,
not under the miner config directory.
-1. **Install the SQLite plugin** in Grafana — the same one the maintainer `GittensoryDB` datasource uses:
+1. **Install the SQLite plugin** in Grafana — the same one the maintainer `LoopoverDB` datasource uses:
```sh
GF_INSTALL_PLUGINS=frser-sqlite-datasource
diff --git a/packages/gittensory-miner/docs/operations-runbook.md b/packages/gittensory-miner/docs/operations-runbook.md
index 13406d1ec2..e4504f384e 100644
--- a/packages/gittensory-miner/docs/operations-runbook.md
+++ b/packages/gittensory-miner/docs/operations-runbook.md
@@ -2,7 +2,7 @@
Operator-facing runbook for **local SQLite state**: what the concurrency guarantees actually mean, how to recover from corruption, what to do when two miner processes collide on the same files, and how schema upgrades migrate your on-disk ledgers after a package update.
-> **Scope:** AMS local stores only. For laptop/fleet deployment layout see [`../DEPLOYMENT.md`](../DEPLOYMENT.md). For Grafana setup see [#5190](https://github.com/JSONbored/gittensory/issues/5190). For the optional hosted discovery plane see [`discovery-plane-operator-guide.md`](discovery-plane-operator-guide.md). This runbook does **not** cover the self-hosted **review stack** (Orb/API/GittensoryDB).
+> **Scope:** AMS local stores only. For laptop/fleet deployment layout see [`../DEPLOYMENT.md`](../DEPLOYMENT.md). For Grafana setup see [#5190](https://github.com/JSONbored/gittensory/issues/5190). For the optional hosted discovery plane see [`discovery-plane-operator-guide.md`](discovery-plane-operator-guide.md). This runbook does **not** cover the self-hosted **review stack** (Orb/API/LoopoverDB).
## Local state at a glance
diff --git a/prometheus/prometheus.yml b/prometheus/prometheus.yml
index 99e9565e08..66b8b18e10 100644
--- a/prometheus/prometheus.yml
+++ b/prometheus/prometheus.yml
@@ -1,4 +1,4 @@
-# Prometheus scrape config for gittensory self-host (#980 observability).
+# Prometheus scrape config for loopover self-host (#980 observability).
# Activated via: docker compose --profile observability up
global:
scrape_interval: 15s
@@ -18,7 +18,7 @@ alerting:
scrape_configs:
- job_name: gittensory
static_configs:
- - targets: ["gittensory:8787"]
+ - targets: ["loopover:8787"]
metrics_path: /metrics
scrape_interval: 15s
scrape_timeout: 10s
diff --git a/prometheus/rules/alerts.yml b/prometheus/rules/alerts.yml
index 8543bf46a2..defa84a204 100644
--- a/prometheus/rules/alerts.yml
+++ b/prometheus/rules/alerts.yml
@@ -226,7 +226,7 @@ groups:
# consumes more than 80% of max_connections for 10m; use PgBouncer or lower app concurrency.
expr: |
(
- sum(pg_stat_activity_count{datname="gittensory"})
+ sum(pg_stat_activity_count{datname="loopover"})
/
max(pg_settings_max_connections)
) > 0.80
@@ -241,7 +241,7 @@ groups:
- alert: GittensoryPostgresLockWaits
# Wait-event labels are emitted by the postgres_exporter stat_activity collector. Any sustained
# lock wait means a write path is blocked and queue processing can appear stuck.
- expr: sum(pg_stat_activity_count{datname="gittensory", wait_event_type="Lock"}) > 0
+ expr: sum(pg_stat_activity_count{datname="loopover", wait_event_type="Lock"}) > 0
for: 5m
labels:
severity: warning
@@ -253,7 +253,7 @@ groups:
- alert: GittensoryPostgresSlowTransaction
# Long active transactions are the self-host proxy for slow/problem queries without requiring
# pg_stat_statements or superuser-only setup.
- expr: max(pg_stat_activity_max_tx_duration{datname="gittensory"}) > 120
+ expr: max(pg_stat_activity_max_tx_duration{datname="loopover"}) > 120
for: 5m
labels:
severity: warning
@@ -264,7 +264,7 @@ groups:
- alert: GittensoryPostgresDeadlocks
# Deadlocks should be effectively zero; even a low rate points at competing write paths.
- expr: rate(pg_stat_database_deadlocks{datname="gittensory"}[5m]) > 0
+ expr: rate(pg_stat_database_deadlocks{datname="loopover"}[5m]) > 0
for: 2m
labels:
severity: warning
@@ -276,7 +276,7 @@ groups:
- alert: GittensoryPostgresDatabaseGrowingFast
# Growth over a 6h window smooths normal small-table churn while catching runaway queue/audit growth.
# 262144 bytes/s is roughly 5.4 GiB over 6h.
- expr: deriv(pg_database_size_bytes{datname="gittensory"}[6h]) > 262144
+ expr: deriv(pg_database_size_bytes{datname="loopover"}[6h]) > 262144
for: 30m
labels:
severity: warning
@@ -289,15 +289,15 @@ groups:
# Autovacuum pressure: high dead tuple ratio and enough absolute dead rows to avoid tiny-table noise.
expr: |
(
- sum(pg_stat_user_tables_n_dead_tup{datname="gittensory"})
+ sum(pg_stat_user_tables_n_dead_tup{datname="loopover"})
/
clamp_min(
- sum(pg_stat_user_tables_n_live_tup{datname="gittensory"} + pg_stat_user_tables_n_dead_tup{datname="gittensory"}),
+ sum(pg_stat_user_tables_n_live_tup{datname="loopover"} + pg_stat_user_tables_n_dead_tup{datname="loopover"}),
1
)
) > 0.20
and
- sum(pg_stat_user_tables_n_dead_tup{datname="gittensory"}) > 10000
+ sum(pg_stat_user_tables_n_dead_tup{datname="loopover"}) > 10000
for: 30m
labels:
severity: warning
@@ -314,9 +314,9 @@ groups:
labels:
severity: warning
annotations:
- summary: "No retained gittensory database backup found"
+ summary: "No retained loopover database backup found"
description: "The backup profile is exposing metrics, but {{ $labels.target }} has no retained backup file after 2h."
- runbook: "Run `docker compose --profile backup run --rm backup sh /backup.sh` and inspect the gittensory-backups volume. For Postgres, confirm DATABASE_URL is available to the backup service."
+ runbook: "Run `docker compose --profile backup run --rm backup sh /backup.sh` and inspect the loopover-backups volume. For Postgres, confirm DATABASE_URL is available to the backup service."
- alert: GittensoryBackupStale
# Default backup loop is daily. 26h allows one missed scrape/restart window before warning.
diff --git a/scripts/backup-metrics.sh b/scripts/backup-metrics.sh
index ad5fb6d621..8d73fc2f18 100644
--- a/scripts/backup-metrics.sh
+++ b/scripts/backup-metrics.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Expose retained backup freshness from the gittensory-backups volume in Prometheus text format.
+# Expose retained backup freshness from the loopover-backups volume in Prometheus text format.
# Intended for the backup-exporter compose sidecar; it never touches the live database.
set -eu
diff --git a/scripts/backup.sh b/scripts/backup.sh
index 628b976855..a7cfad4ecd 100644
--- a/scripts/backup.sh
+++ b/scripts/backup.sh
@@ -2,7 +2,7 @@
# Self-host backup: active DB backup (Postgres dump or online SQLite backup) + a Qdrant snapshot, with retention.
# Run by the `backup` compose service (--profile backup) on a loop, or on demand:
# docker compose --profile backup run --rm backup sh /scripts/backup.sh
-# Backups land in the `gittensory-backups` volume at /backups/{postgres,sqlite,qdrant}.
+# Backups land in the `loopover-backups` volume at /backups/{postgres,sqlite,qdrant}.
set -eu
# shellcheck source=selfhost-pg-url.sh
@@ -32,7 +32,7 @@ normalize_backup_retain() {
TS=$(date -u +%Y%m%dT%H%M%SZ)
RETAIN=$(normalize_backup_retain "${BACKUP_RETAIN:-7}")
-DB=${DATABASE_PATH:-/data/gittensory.sqlite}
+DB=${DATABASE_PATH:-/data/loopover.sqlite}
PG_DB="${GITTENSORY_BACKUP_SOURCE_DATABASE_URL:-${DATABASE_URL:-}}"
OUT=${BACKUP_OUT_DIR:-/backups}
PGPASSFILE_CREATED=""
@@ -233,7 +233,7 @@ prepare_pg_env() {
exit 1
;;
esac
- PGPASSFILE_CREATED=$(mktemp "${TMPDIR:-/tmp}/gittensory-pgpass.XXXXXX")
+ PGPASSFILE_CREATED=$(mktemp "${TMPDIR:-/tmp}/loopover-pgpass.XXXXXX")
chmod 600 "$PGPASSFILE_CREATED"
printf '*:*:*:*:%s\n' "$(pgpass_escape "$PGPASSWORD_VALUE")" > "$PGPASSFILE_CREATED"
export PGPASSFILE="$PGPASSFILE_CREATED"
@@ -248,7 +248,7 @@ case "$PG_DB" in
exit 1
fi
prepare_pg_env
- POSTGRES_OUT="$OUT/postgres/gittensory-$TS.dump"
+ POSTGRES_OUT="$OUT/postgres/loopover-$TS.dump"
pg_dump -Fc -f "$POSTGRES_OUT" "$PG_SANITIZED_URL"
POSTGRES_MANIFEST_FILE="postgres/$(basename "$POSTGRES_OUT")"
POSTGRES_MANIFEST_BYTES=$(file_bytes "$POSTGRES_OUT")
@@ -256,7 +256,7 @@ case "$PG_DB" in
;;
*)
if [ -f "$DB" ]; then
- SQLITE_OUT="$OUT/sqlite/gittensory-$TS.sqlite"
+ SQLITE_OUT="$OUT/sqlite/loopover-$TS.sqlite"
# `.backup` can exit 0 while writing a partial/corrupt file, so verify the result
# (non-empty AND `PRAGMA integrity_check` == ok) before we gzip it or let retention
# prune older, good backups. A failed backup must be loud, not silently "successful".
diff --git a/scripts/deploy-selfhost-image.sh b/scripts/deploy-selfhost-image.sh
index 419de5d48c..68b648dac9 100755
--- a/scripts/deploy-selfhost-image.sh
+++ b/scripts/deploy-selfhost-image.sh
@@ -15,7 +15,7 @@
set -euo pipefail
ENV_FILE="${SELFHOST_ENV_FILE:-.env}"
-SERVICE="${SELFHOST_SERVICE:-gittensory}"
+SERVICE="${SELFHOST_SERVICE:-loopover}"
HEALTH_TIMEOUT_SECONDS="${SELFHOST_HEALTH_TIMEOUT_SECONDS:-180}"
DEFAULT_IMAGE="ghcr.io/jsonbored/gittensory-selfhost:latest"
diff --git a/scripts/deploy-selfhost-prebuilt.sh b/scripts/deploy-selfhost-prebuilt.sh
index 33e3a2c28c..039e6cb747 100755
--- a/scripts/deploy-selfhost-prebuilt.sh
+++ b/scripts/deploy-selfhost-prebuilt.sh
@@ -14,7 +14,7 @@ set -euo pipefail
ENV_FILE="${SELFHOST_ENV_FILE:-.env}"
NODE_IMAGE="${SELFHOST_NODE_IMAGE:-public.ecr.aws/docker/library/node:24-slim}"
-SERVICE="${SELFHOST_SERVICE:-gittensory}"
+SERVICE="${SELFHOST_SERVICE:-loopover}"
SKIP_SENTRY_UPLOAD="${SELFHOST_SKIP_SENTRY_UPLOAD:-0}"
SENTRY_CLI_PACKAGE="${SENTRY_CLI_PACKAGE:-@sentry/cli@3.6.0}"
@@ -117,7 +117,7 @@ require_cmd docker
docker compose version >/dev/null
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
- echo "error: run this script from the gittensory git checkout" >&2
+ echo "error: run this script from the loopover git checkout" >&2
exit 1
fi
diff --git a/scripts/export-grafana-reporting-db.sh b/scripts/export-grafana-reporting-db.sh
index e48f0e5fbd..4aef9f9d7d 100644
--- a/scripts/export-grafana-reporting-db.sh
+++ b/scripts/export-grafana-reporting-db.sh
@@ -9,10 +9,10 @@ set -eu
# purely so a test can simulate "the script logic changed" without editing this file.
SCRIPT_VERSION="${GITTENSORY_REPORTING_SCRIPT_VERSION:-2}"
-APP_DB="${GITTENSORY_REPORTING_SOURCE_DB:-/appdb/gittensory.sqlite}"
+APP_DB="${GITTENSORY_REPORTING_SOURCE_DB:-/appdb/loopover.sqlite}"
PG_DB="${GITTENSORY_REPORTING_SOURCE_DATABASE_URL:-${DATABASE_URL:-}}"
OUT_DIR="${GITTENSORY_REPORTING_DIR:-/reporting}"
-OUT_DB="${GITTENSORY_REPORTING_DB:-$OUT_DIR/gittensory-reporting.sqlite}"
+OUT_DB="${GITTENSORY_REPORTING_DB:-$OUT_DIR/loopover-reporting.sqlite}"
TMP_DB="${OUT_DB}.tmp"
FINGERPRINT_FILE="${OUT_DB}.fingerprint"
CSV_TMP_DIR="$(mktemp -d)"
diff --git a/scripts/migrate-selfhost-sqlite-to-postgres.ts b/scripts/migrate-selfhost-sqlite-to-postgres.ts
index 8e4653f8d2..656290fa3f 100644
--- a/scripts/migrate-selfhost-sqlite-to-postgres.ts
+++ b/scripts/migrate-selfhost-sqlite-to-postgres.ts
@@ -43,7 +43,7 @@ rolled-back dry run. Pass --execute to commit the copy. Prefer DATABASE_URL over
the Postgres credential is not exposed through process command lines.
Options:
- --sqlite SQLite source file. Defaults to DATABASE_PATH or /data/gittensory.sqlite.
+ --sqlite SQLite source file. Defaults to DATABASE_PATH or /data/loopover.sqlite.
--postgres-url Postgres target URL. Defaults to DATABASE_URL; avoid this on shared hosts.
--migrations-dir Migration directory. Defaults to migrations.
--execute Commit the copy. Omit for a rollback dry run.
@@ -54,7 +54,7 @@ Options:
function parseArgs(argv: string[]): Options {
const opts: Options = {
- sqlitePath: process.env.DATABASE_PATH ?? "/data/gittensory.sqlite",
+ sqlitePath: process.env.DATABASE_PATH ?? "/data/loopover.sqlite",
postgresUrl: process.env.DATABASE_URL ?? "",
migrationsDir: process.env.MIGRATIONS_DIR ?? "migrations",
execute: false,
diff --git a/scripts/selfhost-docker-prune.sh b/scripts/selfhost-docker-prune.sh
index 7bf53dda08..1ffcd35b4e 100755
--- a/scripts/selfhost-docker-prune.sh
+++ b/scripts/selfhost-docker-prune.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-# Automated Docker resource hygiene for a 24/7 self-hosted gittensory stack (#audit-rate-headroom). Runs on
-# the HOST (via the systemd timer in systemd/gittensory-docker-prune.{service,timer}.example), not as a
+# Automated Docker resource hygiene for a 24/7 self-hosted loopover stack (#audit-rate-headroom). Runs on
+# the HOST (via the systemd timer in systemd/loopover-docker-prune.{service,timer}.example), not as a
# compose service: reclaiming unused images and build cache needs real Docker daemon access, which this
# repo deliberately does not grant to any container (see docker-compose.yml's docker-proxy and runner
# service comments on why raw docker.sock exposure into a container is avoided).
@@ -22,7 +22,7 @@
# itself been stopped for at least RETAIN_HOURS is ever removed.
#
# SAFE BY DESIGN: only prunes stopped containers, unused images, and build cache -- NEVER volumes
-# (gittensory-data, gittensory-backups, postgres-data, qdrant-storage, runner-work, etc.), so it cannot
+# (loopover-data, loopover-backups, postgres-data, qdrant-storage, runner-work, etc.), so it cannot
# delete application data, backups, vector-store state, or a runner's registration/job data.
#
# Usage:
diff --git a/scripts/selfhost-init-secrets.sh b/scripts/selfhost-init-secrets.sh
index 4a6175895f..af9ea3534c 100755
--- a/scripts/selfhost-init-secrets.sh
+++ b/scripts/selfhost-init-secrets.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-# Ensure every Docker Compose secret file docker-compose.yml's `gittensory` service references
+# Ensure every Docker Compose secret file docker-compose.yml's `loopover` service references
# actually exists on disk, so `docker compose build`/`up` never fails on a missing `secrets:` source
# file -- Compose requires the file to exist even for an operator who has never touched this feature
# and is relying entirely on inline .env values (see secrets/README.md: an inline value always wins
@@ -34,8 +34,8 @@ SECRETS_DIR="secrets"
SECRET_FILES=(
"github_app_private_key.pem"
"github_webhook_secret.txt"
- "gittensory_api_token.txt"
- "gittensory_mcp_token.txt"
+ "loopover_api_token.txt"
+ "loopover_mcp_token.txt"
"internal_job_token.txt"
"selfhost_setup_token.txt"
"token_encryption_secret.txt"
diff --git a/scripts/selfhost-post-update-check.sh b/scripts/selfhost-post-update-check.sh
index 77ef7f94bd..b23d1cf493 100755
--- a/scripts/selfhost-post-update-check.sh
+++ b/scripts/selfhost-post-update-check.sh
@@ -2,14 +2,14 @@
# Post-update verification for a self-host instance (#1823).
#
# Run after deploy-selfhost-image.sh, deploy-selfhost-prebuilt.sh, or any manual
-# `docker compose up -d --no-deps gittensory` that ships a new app image.
+# `docker compose up -d --no-deps loopover` that ships a new app image.
#
# Checks /ready, compose health, .env release metadata, and the running container image.
# Does not modify .env, volumes, gittensory-config/, or any profile service.
set -euo pipefail
ENV_FILE="${SELFHOST_ENV_FILE:-.env}"
-SERVICE="${SELFHOST_SERVICE:-gittensory}"
+SERVICE="${SELFHOST_SERVICE:-loopover}"
PORT="${PORT:-8787}"
READY_URL="${SELFHOST_READY_URL:-http://127.0.0.1:${PORT}/ready}"
@@ -32,7 +32,7 @@ fi
# Retry, don't single-probe: `docker compose up -d` returns as soon as the container STARTS, well before
# the app inside has bound its port -- a single immediate curl reliably false-fails on a normal boot. Budget
-# matches the gittensory service's own Docker healthcheck start_period (60s, docker-compose.yml) plus margin,
+# matches the loopover service's own Docker healthcheck start_period (60s, docker-compose.yml) plus margin,
# polling often enough that a normal ~15-20s boot returns almost immediately once actually ready.
READY_RETRIES="${SELFHOST_READY_RETRIES:-45}"
READY_RETRY_DELAY_SECONDS="${SELFHOST_READY_RETRY_DELAY_SECONDS:-2}"
diff --git a/scripts/selfhost-update.sh b/scripts/selfhost-update.sh
index 08de0d1cb3..f341a06e69 100755
--- a/scripts/selfhost-update.sh
+++ b/scripts/selfhost-update.sh
@@ -14,9 +14,9 @@
# - gittensory-config/ (private per-repo .gittensory.yml policy)
# - .deploy-backups/ (operator deploy-backup snapshots)
# - any *.local or docker-compose.local-*.yml compose override, or alertmanager config files
-# - named data volumes (gittensory-data, gittensory-pg, qdrant-data, gittensory-backups,
+# - named data volumes (loopover-data, loopover-pg, qdrant-data, loopover-backups,
# grafana-data) -- untouched because this script only fetches source and rebuilds the
-# gittensory app image; it never runs `docker volume` commands or touches compose profiles.
+# loopover app image; it never runs `docker volume` commands or touches compose profiles.
#
# Optional knobs:
# SELFHOST_UPDATE_REMOTE=upstream SELFHOST_UPDATE_BRANCH=main ./scripts/selfhost-update.sh
@@ -39,7 +39,7 @@ require_cmd() {
require_cmd git
if ! git -C "$SCRIPT_DIR/.." rev-parse --is-inside-work-tree >/dev/null 2>&1; then
- echo "error: run this script from the gittensory git checkout" >&2
+ echo "error: run this script from the loopover git checkout" >&2
exit 1
fi
diff --git a/scripts/verify-backup.sh b/scripts/verify-backup.sh
index 6781a1fd35..69207fc925 100644
--- a/scripts/verify-backup.sh
+++ b/scripts/verify-backup.sh
@@ -6,7 +6,7 @@
# restores the Postgres dump into a throwaway database and runs a sanity query — it refuses to touch the live
# database. Run on demand (newest backup, or a specific file):
# docker compose --profile backup run --rm backup sh /scripts/verify-backup.sh
-# docker compose --profile backup run --rm backup sh /scripts/verify-backup.sh /backups/postgres/gittensory-.dump
+# docker compose --profile backup run --rm backup sh /scripts/verify-backup.sh /backups/postgres/loopover-.dump
set -eu
OUT=${BACKUP_OUT_DIR:-/backups}
@@ -149,7 +149,7 @@ pg_connect_arg() {
# Host/port/dbname/user are wildcarded: each passfile is single-purpose, deleted at the end of this
# run via the `cleanup` trap, so there's no value in re-deriving the exact host/port/dbname libpq will
# resolve -- which the query string can override anyway -- just to match them precisely.
- pg_passfile=$(mktemp "${TMPDIR:-/tmp}/gittensory-pgpass.XXXXXX")
+ pg_passfile=$(mktemp "${TMPDIR:-/tmp}/loopover-pgpass.XXXXXX")
chmod 600 "$pg_passfile"
printf '*:*:*:*:%s\n' "$(pgpass_escape "$pg_password_value")" > "$pg_passfile"
PG_PASSFILES="$PG_PASSFILES $pg_passfile"
diff --git a/secrets/README.md b/secrets/README.md
index 16276adc9a..a85b8e3cc2 100644
--- a/secrets/README.md
+++ b/secrets/README.md
@@ -46,7 +46,7 @@ To use a secret file instead of an inline `.env` value:
```sh
cp /path/to/your-downloaded-key.pem secrets/github_app_private_key.pem
```
-3. Restart the `gittensory` service (`docker compose up -d --no-deps gittensory`, or run
+3. Restart the `loopover` service (`docker compose up -d --no-deps loopover`, or run
`./scripts/selfhost-update.sh`).
Leave each file at the `644` the init script (`scripts/selfhost-init-secrets.sh`) sets by default —
@@ -58,8 +58,8 @@ see the tradeoff explained above for why `600` breaks the app's own ability to r
|---|---|---|
| `github_app_private_key.pem` | `GITHUB_APP_PRIVATE_KEY_FILE` | Your GitHub App's private key (PEM). |
| `github_webhook_secret.txt` | `GITHUB_WEBHOOK_SECRET_FILE` | HMAC key GitHub webhook deliveries are verified against. |
-| `gittensory_api_token.txt` | `GITTENSORY_API_TOKEN_FILE` | Server-to-server API bearer token. |
-| `gittensory_mcp_token.txt` | `GITTENSORY_MCP_TOKEN_FILE` | Shared MCP bearer token. |
+| `loopover_api_token.txt` | `GITTENSORY_API_TOKEN_FILE` | Server-to-server API bearer token. |
+| `loopover_mcp_token.txt` | `GITTENSORY_MCP_TOKEN_FILE` | Shared MCP bearer token. |
| `internal_job_token.txt` | `INTERNAL_JOB_TOKEN_FILE` | Gates internal-only routes (e.g. `/v1/internal/*`). |
| `selfhost_setup_token.txt` | `SELFHOST_SETUP_TOKEN_FILE` | Unlocks the first-run `/setup` wizard. |
| `token_encryption_secret.txt` | `TOKEN_ENCRYPTION_SECRET_FILE` | AES-256-GCM master secret for maintainer BYOK keys at rest. |
@@ -70,7 +70,7 @@ see the tradeoff explained above for why `600` breaks the app's own ability to r
This is not the full list of every secret-shaped env var the stack supports (AI provider API keys,
Discord/Slack webhooks, Postgres/Grafana credentials for their optional profiles, etc.) — it covers
-the vars used by the always-on `gittensory` service. The same `_FILE` convention works for any
+the vars used by the always-on `loopover` service. The same `_FILE` convention works for any
of those too; add a matching `secrets:` entry in `docker-compose.yml` (or a
`docker-compose.override.yml`) if you want the same treatment for one of them.
diff --git a/src/server.ts b/src/server.ts
index a263373cf3..cffa8d9215 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -225,7 +225,7 @@ function buildSqliteBackend(
consume: (m: JobMessage) => Promise,
): Backend {
const sqlite = new DatabaseSync(
- process.env.DATABASE_PATH ?? "/data/gittensory.sqlite",
+ process.env.DATABASE_PATH ?? "/data/loopover.sqlite",
);
sqlite.exec(
"PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON; PRAGMA busy_timeout = 5000;",
diff --git a/systemd/gittensory-miner.service.example b/systemd/gittensory-miner.service.example
index 2250ff1ef7..761d3998a8 100644
--- a/systemd/gittensory-miner.service.example
+++ b/systemd/gittensory-miner.service.example
@@ -5,7 +5,7 @@
# WHY A PERSISTENT SERVICE, NOT A .timer: `gittensory-miner loop` is a long-running daemon that schedules its
# own cycles internally (kill-switch check -> run-loop boundary gate -> attempt -> loop-closure -> reentry), so
# it is a Type=simple service supervised by systemd, NOT a oneshot unit fired by a .timer. (Contrast
-# gittensory-docker-prune.service.example, which IS a genuine periodic batch and therefore does pair with a
+# loopover-docker-prune.service.example, which IS a genuine periodic batch and therefore does pair with a
# .timer.) See DEPLOYMENT.md's "Bare-host (systemd, no Docker)" section.
#
# Install (adjust the placeholders below to your host):
diff --git a/systemd/gittensory-docker-prune.service.example b/systemd/loopover-docker-prune.service.example
similarity index 54%
rename from systemd/gittensory-docker-prune.service.example
rename to systemd/loopover-docker-prune.service.example
index a88ee988bd..fa133f3047 100644
--- a/systemd/gittensory-docker-prune.service.example
+++ b/systemd/loopover-docker-prune.service.example
@@ -1,27 +1,27 @@
-# Runs scripts/selfhost-docker-prune.sh on a schedule (paired with gittensory-docker-prune.timer.example) to
+# Runs scripts/selfhost-docker-prune.sh on a schedule (paired with loopover-docker-prune.timer.example) to
# reclaim unused Docker images and build cache before disk fills up on a long-running self-host deployment.
#
-# Install (adjust the path below to wherever you cloned/deployed gittensory):
-# sudo cp systemd/gittensory-docker-prune.service.example /etc/systemd/system/gittensory-docker-prune.service
-# sudo cp systemd/gittensory-docker-prune.timer.example /etc/systemd/system/gittensory-docker-prune.timer
-# sudo $EDITOR /etc/systemd/system/gittensory-docker-prune.service # fix WorkingDirectory / ExecStart path
+# Install (adjust the path below to wherever you cloned/deployed loopover):
+# sudo cp systemd/loopover-docker-prune.service.example /etc/systemd/system/loopover-docker-prune.service
+# sudo cp systemd/loopover-docker-prune.timer.example /etc/systemd/system/loopover-docker-prune.timer
+# sudo $EDITOR /etc/systemd/system/loopover-docker-prune.service # fix WorkingDirectory / ExecStart path
# sudo systemctl daemon-reload
-# sudo systemctl enable --now gittensory-docker-prune.timer
+# sudo systemctl enable --now loopover-docker-prune.timer
#
# This is a HOST-level unit, not a Docker Compose service: reclaiming images/build-cache needs real Docker
# daemon access, which no container in docker-compose.yml is granted (see that file's docker-proxy and
# runner service comments for why raw /var/run/docker.sock exposure into a container is avoided).
[Unit]
-Description=Gittensory self-host Docker resource hygiene (image + build-cache prune)
+Description=LoopOver self-host Docker resource hygiene (image + build-cache prune)
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
-# REQUIRED: point this at wherever you cloned gittensory.
-WorkingDirectory=/opt/gittensory
-ExecStart=/bin/sh /opt/gittensory/scripts/selfhost-docker-prune.sh
+# REQUIRED: point this at wherever you cloned loopover.
+WorkingDirectory=/opt/loopover
+ExecStart=/bin/sh /opt/loopover/scripts/selfhost-docker-prune.sh
# Optional: override the default 7-day (168h) safety window before an unused image/build-cache entry is
# eligible for removal.
# Environment=GITTENSORY_DOCKER_PRUNE_RETAIN_HOURS=168
diff --git a/systemd/gittensory-docker-prune.timer.example b/systemd/loopover-docker-prune.timer.example
similarity index 56%
rename from systemd/gittensory-docker-prune.timer.example
rename to systemd/loopover-docker-prune.timer.example
index 7fb52f8459..f9f959b0cc 100644
--- a/systemd/gittensory-docker-prune.timer.example
+++ b/systemd/loopover-docker-prune.timer.example
@@ -1,7 +1,7 @@
-# Pairs with gittensory-docker-prune.service.example. See that file for install instructions.
+# Pairs with loopover-docker-prune.service.example. See that file for install instructions.
[Unit]
-Description=Run gittensory-docker-prune.service daily
+Description=Run loopover-docker-prune.service daily
[Timer]
OnCalendar=daily
diff --git a/test/unit/ams-ledgers-datasource.test.ts b/test/unit/ams-ledgers-datasource.test.ts
index 5c83ce1e64..f7380e84e5 100644
--- a/test/unit/ams-ledgers-datasource.test.ts
+++ b/test/unit/ams-ledgers-datasource.test.ts
@@ -53,7 +53,7 @@ describe("AMS ledger Grafana datasources (#5184)", () => {
for (const ds of amsDatasources) {
expect(existingUids.has(ds.uid)).toBe(false);
}
- // the maintainer GittensoryDB datasource still exists — this change added a file, it did not edit one
+ // the maintainer LoopoverDB datasource still exists — this change added a file, it did not edit one
expect(existingUids.has("gittensory-db")).toBe(true);
});
});
diff --git a/test/unit/backup-script.test.ts b/test/unit/backup-script.test.ts
index 31a96271e6..f64fbfc93b 100644
--- a/test/unit/backup-script.test.ts
+++ b/test/unit/backup-script.test.ts
@@ -169,7 +169,7 @@ describe("scripts/backup.sh sqlite online-backup verification (#2084)", () => {
"ts",
]);
expect(manifest.postgres).toBeNull();
- expect(manifest.sqlite?.file).toMatch(/^sqlite\/gittensory-\d{8}T\d{6}Z\.sqlite\.gz$/);
+ expect(manifest.sqlite?.file).toMatch(/^sqlite\/loopover-\d{8}T\d{6}Z\.sqlite\.gz$/);
expect(manifest.sqlite?.bytes).toBe(
statSync(join(harness.outDir, manifest.sqlite!.file)).size,
);
@@ -181,7 +181,7 @@ describe("scripts/backup.sh sqlite online-backup verification (#2084)", () => {
expect(res.status).toBe(0);
const manifest = readManifest(harness);
- expect(manifest.sqlite?.file).toMatch(/^sqlite\/gittensory-\d{8}T\d{6}Z\.sqlite\.gz$/);
+ expect(manifest.sqlite?.file).toMatch(/^sqlite\/loopover-\d{8}T\d{6}Z\.sqlite\.gz$/);
expect(manifest.postgres).toBeNull();
expect(manifest.qdrant.file).toBe("qdrant/qdrant-snapshot-123.snap");
expect(readFileSync(join(harness.outDir, manifest.qdrant.file!), "utf8")).toBe(
@@ -196,7 +196,7 @@ describe("scripts/backup.sh sqlite online-backup verification (#2084)", () => {
expect(res.stderr).toContain("BACKUP_RETAIN=0");
const manifest = readManifest(harness);
expect(manifest.retain).toBe(1);
- expect(manifest.sqlite?.file).toMatch(/^sqlite\/gittensory-\d{8}T\d{6}Z\.sqlite\.gz$/);
+ expect(manifest.sqlite?.file).toMatch(/^sqlite\/loopover-\d{8}T\d{6}Z\.sqlite\.gz$/);
expect(existsSync(join(harness.outDir, manifest.sqlite!.file))).toBe(true);
expect(readdirSync(join(harness.outDir, "sqlite"))).toHaveLength(1);
});
@@ -224,7 +224,7 @@ describe("scripts/backup.sh sqlite online-backup verification (#2084)", () => {
expect(res.status).toBe(0);
expect(res.stdout).toContain("[backup] postgres ->");
const manifest = readManifest(harness);
- expect(manifest.postgres?.file).toMatch(/^postgres\/gittensory-\d{8}T\d{6}Z\.dump$/);
+ expect(manifest.postgres?.file).toMatch(/^postgres\/loopover-\d{8}T\d{6}Z\.dump$/);
expect(manifest.postgres?.bytes).toBe(
statSync(join(harness.outDir, manifest.postgres!.file)).size,
);
diff --git a/test/unit/docker-compose-override-example.test.ts b/test/unit/docker-compose-override-example.test.ts
index 17409b57fa..4f5da4b538 100644
--- a/test/unit/docker-compose-override-example.test.ts
+++ b/test/unit/docker-compose-override-example.test.ts
@@ -10,7 +10,7 @@ function readYaml(path: string): Record {
return value as Record;
}
-// A burst of CI jobs (--profile runners) can starve the main `gittensory` app of CPU on a shared host
+// A burst of CI jobs (--profile runners) can starve the main `loopover` app of CPU on a shared host
// with no limits set (the default). docker-compose.override.yml.example documents a proven cpu_shares +
// cpus pattern for that case -- pure structural checks only (no `docker` CLI invocation: the self-hosted
// runner container this actually runs on does not have Docker-in-Docker access, so a test that shells out
@@ -22,7 +22,7 @@ describe("docker-compose.override.yml.example", () => {
const exampleServices = Object.keys(example.services as Record);
const baseServices = Object.keys(base.services as Record);
- expect(exampleServices).toEqual(["gittensory", "runner"]);
+ expect(exampleServices).toEqual(["loopover", "runner"]);
for (const name of exampleServices) {
expect(baseServices).toContain(name);
}
@@ -32,7 +32,7 @@ describe("docker-compose.override.yml.example", () => {
const example = readYaml("docker-compose.override.yml.example");
const services = example.services as Record>;
- const appShares = Number(services.gittensory?.cpu_shares);
+ const appShares = Number(services.loopover?.cpu_shares);
const runnerShares = Number(services.runner?.cpu_shares);
expect(Number.isFinite(appShares) && Number.isFinite(runnerShares)).toBe(true);
expect(appShares).toBeGreaterThan(runnerShares);
diff --git a/test/unit/docs-selfhost-update-rollback.test.ts b/test/unit/docs-selfhost-update-rollback.test.ts
index b3fc8b155d..a4b7aea365 100644
--- a/test/unit/docs-selfhost-update-rollback.test.ts
+++ b/test/unit/docs-selfhost-update-rollback.test.ts
@@ -23,7 +23,7 @@ describe("self-host update + rollback docs (#1823)", () => {
expect(operations).toContain("Post-update checklist");
expect(operations).toContain("Operator-owned");
expect(operations).toContain("gittensory-config/");
- expect(operations).toContain("gittensory-data");
+ expect(operations).toContain("loopover-data");
expect(operations).toContain("Migrations are forward-only");
});
diff --git a/test/unit/selfhost-backup-script.test.ts b/test/unit/selfhost-backup-script.test.ts
index e470113f6e..0374d8c012 100644
--- a/test/unit/selfhost-backup-script.test.ts
+++ b/test/unit/selfhost-backup-script.test.ts
@@ -120,7 +120,7 @@ describe("self-host backup script", () => {
const postgresBackups = readdirSync(join(root, "backups", "postgres"));
expect(output).toContain("[backup] postgres ->");
expect(postgresBackups).toHaveLength(1);
- expect(postgresBackups[0]).toMatch(/^gittensory-\d{8}T\d{6}Z\.dump$/);
+ expect(postgresBackups[0]).toMatch(/^loopover-\d{8}T\d{6}Z\.dump$/);
expect(readdirSync(join(root, "backups", "sqlite"))).toEqual([]);
});
@@ -151,7 +151,7 @@ describe("self-host backup script", () => {
// basename only, not a hardcoded /tmp/ prefix: mktemp resolves under $TMPDIR, which macOS sets to a
// per-user private directory rather than /tmp (the CI runner's Linux environment does default to /tmp,
// but the assertion shouldn't assume that).
- expect(passfilePath).toMatch(/\/gittensory-pgpass\.[^/]+$/);
+ expect(passfilePath).toMatch(/\/loopover-pgpass\.[^/]+$/);
expect(passfileContent).toBe("*:*:*:*:SuperSecret123!");
expect(passfileModeOk).toBe("yes");
});
@@ -351,7 +351,7 @@ describe("self-host backup script", () => {
const sqliteBackups = readdirSync(join(root, "backups", "sqlite"));
expect(output).toContain("[backup] sqlite ->");
expect(sqliteBackups).toHaveLength(1);
- expect(sqliteBackups[0]).toMatch(/^gittensory-\d{8}T\d{6}Z\.sqlite\.gz$/);
+ expect(sqliteBackups[0]).toMatch(/^loopover-\d{8}T\d{6}Z\.sqlite\.gz$/);
expect(existsSync(join(root, "backups", "postgres"))).toBe(true);
expect(readdirSync(join(root, "backups", "postgres"))).toEqual([]);
});
diff --git a/test/unit/selfhost-compose-db-health.test.ts b/test/unit/selfhost-compose-db-health.test.ts
index 86ef1381dd..42087e9882 100644
--- a/test/unit/selfhost-compose-db-health.test.ts
+++ b/test/unit/selfhost-compose-db-health.test.ts
@@ -17,7 +17,7 @@ describe("docker-compose.yml — postgres/pgbouncer startup ordering (#2500, #25
it("gates the core app on a healthy postgres and pgbouncer without requiring either profile", () => {
const compose = readYaml("docker-compose.yml");
const services = (compose.services as Record>) ?? {};
- const app = services.gittensory ?? {};
+ const app = services.loopover ?? {};
const dependsOn = app.depends_on as Record;
// redis stays required (always-on service); postgres/pgbouncer/qdrant are all required:false since only
@@ -28,7 +28,7 @@ describe("docker-compose.yml — postgres/pgbouncer startup ordering (#2500, #25
expect(dependsOn.qdrant).toEqual({ condition: "service_healthy", required: false });
});
- it("gives pgbouncer a healthcheck so gittensory's depends_on has a real readiness signal to gate on", () => {
+ it("gives pgbouncer a healthcheck so loopover's depends_on has a real readiness signal to gate on", () => {
const compose = readYaml("docker-compose.yml");
const services = (compose.services as Record>) ?? {};
const pgbouncer = services.pgbouncer ?? {};
@@ -41,7 +41,7 @@ describe("docker-compose.yml — postgres/pgbouncer startup ordering (#2500, #25
expect(healthcheck.retries).toBeGreaterThan(0);
});
- it("still starts pgbouncer only after a healthy postgres (unaffected by the new gittensory dependency)", () => {
+ it("still starts pgbouncer only after a healthy postgres (unaffected by the new loopover dependency)", () => {
const compose = readYaml("docker-compose.yml");
const services = (compose.services as Record>) ?? {};
const pgbouncer = services.pgbouncer ?? {};
diff --git a/test/unit/selfhost-compose-resource-limits.test.ts b/test/unit/selfhost-compose-resource-limits.test.ts
index 501a1e5f8d..033bf8db62 100644
--- a/test/unit/selfhost-compose-resource-limits.test.ts
+++ b/test/unit/selfhost-compose-resource-limits.test.ts
@@ -15,7 +15,7 @@ function readYaml(path: string): Record {
// would be unreliable/environment-dependent here (same constraint as docker-compose-override-example.test.ts).
describe("docker-compose.yml — per-service memory limits (#1828, #2495, #3893)", () => {
const EXPECTED_LIMITS: Record = {
- gittensory: "${GITTENSORY_MEM_LIMIT:-2g}",
+ loopover: "${GITTENSORY_MEM_LIMIT:-2g}",
redis: "${REDIS_MEM_LIMIT:-512m}",
postgres: "${POSTGRES_MEM_LIMIT:-2g}",
qdrant: "${QDRANT_MEM_LIMIT:-2g}",
diff --git a/test/unit/selfhost-grafana-dashboard.test.ts b/test/unit/selfhost-grafana-dashboard.test.ts
index ab02377d6d..f643017f9a 100644
--- a/test/unit/selfhost-grafana-dashboard.test.ts
+++ b/test/unit/selfhost-grafana-dashboard.test.ts
@@ -174,14 +174,14 @@ describe("Gittensory Self-Host Grafana dashboard", () => {
expect(titles).toEqual(expect.arrayContaining(["Postgres & Backups", "Postgres Connections by State", "Postgres Locks & Slow Transactions", "Postgres Size & Table Growth", "Dead Tuples / Autovacuum", "Backup Freshness"]));
expect(targets.some((target) => target.expr === 'pg_up or vector(0)')).toBe(true);
- expect(targets.some((target) => target.expr === 'sum(pg_stat_activity_count{datname="gittensory"}) or vector(0)')).toBe(true);
- expect(targets.some((target) => target.expr === 'sum by (state) (pg_stat_activity_count{datname="gittensory"}) or vector(0)')).toBe(true);
- expect(targets.some((target) => target.expr === 'sum(pg_stat_activity_count{datname="gittensory", wait_event_type="Lock"}) or vector(0)')).toBe(true);
- expect(targets.some((target) => target.expr === 'max(pg_stat_activity_max_tx_duration{datname="gittensory"}) or vector(0)')).toBe(true);
- expect(targets.some((target) => target.expr === 'pg_database_size_bytes{datname="gittensory"} or vector(0)')).toBe(true);
- expect(targets.some((target) => target.expr === 'topk(10, pg_stat_user_tables_n_live_tup{datname="gittensory"}) or vector(0)')).toBe(true);
- expect(targets.some((target) => target.expr === 'topk(10, pg_stat_user_tables_n_dead_tup{datname="gittensory"}) or vector(0)')).toBe(true);
- expect(targets.some((target) => target.expr === 'sum by (relname) (increase(pg_stat_user_tables_autovacuum_count{datname="gittensory"}[1h])) or vector(0)')).toBe(true);
+ expect(targets.some((target) => target.expr === 'sum(pg_stat_activity_count{datname="loopover"}) or vector(0)')).toBe(true);
+ expect(targets.some((target) => target.expr === 'sum by (state) (pg_stat_activity_count{datname="loopover"}) or vector(0)')).toBe(true);
+ expect(targets.some((target) => target.expr === 'sum(pg_stat_activity_count{datname="loopover", wait_event_type="Lock"}) or vector(0)')).toBe(true);
+ expect(targets.some((target) => target.expr === 'max(pg_stat_activity_max_tx_duration{datname="loopover"}) or vector(0)')).toBe(true);
+ expect(targets.some((target) => target.expr === 'pg_database_size_bytes{datname="loopover"} or vector(0)')).toBe(true);
+ expect(targets.some((target) => target.expr === 'topk(10, pg_stat_user_tables_n_live_tup{datname="loopover"}) or vector(0)')).toBe(true);
+ expect(targets.some((target) => target.expr === 'topk(10, pg_stat_user_tables_n_dead_tup{datname="loopover"}) or vector(0)')).toBe(true);
+ expect(targets.some((target) => target.expr === 'sum by (relname) (increase(pg_stat_user_tables_autovacuum_count{datname="loopover"}[1h])) or vector(0)')).toBe(true);
expect(targets.some((target) => target.expr === 'gittensory_backup_files{target=~"postgres|sqlite|qdrant"} or vector(0)')).toBe(true);
});
@@ -189,17 +189,17 @@ describe("Gittensory Self-Host Grafana dashboard", () => {
const alerts = readFileSync(selfhostAlertsPath, "utf8");
expect(alerts).toContain("alert: GittensoryPostgresConnectionPressure");
- expect(alerts).toContain('sum(pg_stat_activity_count{datname="gittensory"})');
+ expect(alerts).toContain('sum(pg_stat_activity_count{datname="loopover"})');
expect(alerts).toContain("alert: GittensoryPostgresLockWaits");
- expect(alerts).toContain('pg_stat_activity_count{datname="gittensory", wait_event_type="Lock"}');
+ expect(alerts).toContain('pg_stat_activity_count{datname="loopover", wait_event_type="Lock"}');
expect(alerts).toContain("alert: GittensoryPostgresSlowTransaction");
- expect(alerts).toContain('pg_stat_activity_max_tx_duration{datname="gittensory"}');
+ expect(alerts).toContain('pg_stat_activity_max_tx_duration{datname="loopover"}');
expect(alerts).toContain("alert: GittensoryPostgresDeadlocks");
- expect(alerts).toContain('pg_stat_database_deadlocks{datname="gittensory"}');
+ expect(alerts).toContain('pg_stat_database_deadlocks{datname="loopover"}');
expect(alerts).toContain("alert: GittensoryPostgresDatabaseGrowingFast");
- expect(alerts).toContain('deriv(pg_database_size_bytes{datname="gittensory"}[6h]) > 262144');
+ expect(alerts).toContain('deriv(pg_database_size_bytes{datname="loopover"}[6h]) > 262144');
expect(alerts).toContain("alert: GittensoryPostgresDeadTuplesHigh");
- expect(alerts).toContain('pg_stat_user_tables_n_dead_tup{datname="gittensory"}');
+ expect(alerts).toContain('pg_stat_user_tables_n_dead_tup{datname="loopover"}');
expect(alerts).toContain("alert: GittensoryBackupMissing");
expect(alerts).toContain('gittensory_backup_files{target=~"postgres|sqlite"} == 0');
expect(alerts).toContain("alert: GittensoryBackupStale");
diff --git a/test/unit/selfhost-image-deploy.test.ts b/test/unit/selfhost-image-deploy.test.ts
index 1d53db8ac9..c325c33d2c 100644
--- a/test/unit/selfhost-image-deploy.test.ts
+++ b/test/unit/selfhost-image-deploy.test.ts
@@ -30,7 +30,7 @@ function createHarness() {
const envPath = join(dir, ".env");
mkdirSync(binDir);
- writeFileSync(join(dir, "docker-compose.yml"), "services:\n gittensory:\n image: old\n");
+ writeFileSync(join(dir, "docker-compose.yml"), "services:\n loopover:\n image: old\n");
writeFileSync(
join(binDir, "docker"),
`#!/usr/bin/env bash
@@ -156,7 +156,7 @@ describe("self-host image deploy script", () => {
// REGRESSION: without this reset, an operator's own docker-compose.override.yml build: block for this
// service silently wins over the pulled image at `up --no-build` time (found deploying live).
expect(harness.readImages()).toContain("build: !reset null");
- expect(harness.readCalls()).toContain("up -d --no-build --no-deps gittensory");
+ expect(harness.readCalls()).toContain("up -d --no-build --no-deps loopover");
expect(harness.readCalls()).not.toContain(" build ");
} finally {
harness.cleanup();
diff --git a/test/unit/selfhost-observability-config.test.ts b/test/unit/selfhost-observability-config.test.ts
index 09108994c9..4b793dc0a1 100644
--- a/test/unit/selfhost-observability-config.test.ts
+++ b/test/unit/selfhost-observability-config.test.ts
@@ -119,15 +119,15 @@ describe("self-host observability trace config", () => {
expect(postgresExporter.profiles).toEqual(["postgres", "pgbouncer"]);
expect(postgresExporter.depends_on?.postgres).toEqual({ condition: "service_healthy" });
expect(postgresExporter.environment).toMatchObject({
- DATA_SOURCE_URI: "postgres:5432/gittensory?sslmode=disable",
- DATA_SOURCE_USER: "gittensory",
+ DATA_SOURCE_URI: "postgres:5432/loopover?sslmode=disable",
+ DATA_SOURCE_USER: "loopover",
DATA_SOURCE_PASS: "${POSTGRES_PASSWORD:-CHANGEME}",
});
expect(backupExporter.profiles).toEqual(["backup"]);
expect(backupExporter.volumes).toEqual(
expect.arrayContaining([
- "gittensory-backups:/backups:ro",
+ "loopover-backups:/backups:ro",
"./scripts:/scripts:ro",
]),
);
diff --git a/test/unit/selfhost-update-script.test.ts b/test/unit/selfhost-update-script.test.ts
index 6a98aa0135..5b5528a517 100644
--- a/test/unit/selfhost-update-script.test.ts
+++ b/test/unit/selfhost-update-script.test.ts
@@ -285,6 +285,6 @@ describe("selfhost-update.sh", () => {
});
expect(result.status).not.toBe(0);
- expect(result.stderr).toContain("run this script from the gittensory git checkout");
+ expect(result.stderr).toContain("run this script from the loopover git checkout");
});
});