Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ coverage
.git
.claude
# The self-host bundle's only entry point is src/server.ts (scripts/build-selfhost.mjs) and `npm ci`
# only ever sees the root package*.json (copied before the rest of the tree) — the gittensory-ui
# only ever sees the root package*.json (copied before the rest of the tree) — the loopover-ui
# workspace app and the test suite are never read during the image build, so keep both out of the
# build context entirely (measured: ~11MB of this repo's ~22MB tracked-file footprint).
apps
test
# Runtime-only private review config and subscription CLI auth must never enter image layers.
gittensory-config
**/gittensory-config
loopover-config
**/loopover-config
**/.codex
auth.json
**/auth.json
Expand Down
29 changes: 15 additions & 14 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Gittensory — sample environment file
# LoopOver — sample environment file
#
# Copy to `.dev.vars` (local) or set as worker vars/secrets (deployed). This file
# lists every operator-facing LOOPOVER_REVIEW_* feature flag plus the names of
Expand All @@ -23,7 +23,7 @@
# a repo only if its own flag is ON *and* the repo is listed here. Empty = no
# repos, so every per-PR feature stays dormant regardless of the flags below.
# Case-insensitive, trimmed; stray commas ignored.
# Example: LOOPOVER_REVIEW_REPOS="JSONbored/gittensory,JSONbored/awesome-claude"
# Example: LOOPOVER_REVIEW_REPOS="JSONbored/loopover,JSONbored/awesome-claude"
LOOPOVER_REVIEW_REPOS=
# GITTENSORY_REVIEW_REPOS= # no longer read (removed by #4777)

Expand Down Expand Up @@ -208,8 +208,8 @@ LOOPOVER_REVIEW_DRAFT=false
# # /setup returns 400; with it, enter the token in the browser form
# # or send an x-setup-token / Bearer header. Never put this token in
# # the URL; query strings leak to logs, proxies, and browser history.
# SETUP_OUTPUT_PATH=/data/gittensory-app.env # overrides where the first-run setup wizard writes the generated
# # GitHub App credentials file. Default: /data/gittensory-app.env.
# SETUP_OUTPUT_PATH=/data/loopover-app.env # overrides where the first-run setup wizard writes the generated
# # GitHub App credentials file. Default: /data/loopover-app.env.
# ADMIN_GITHUB_LOGINS=your-github-login # REQUIRED for control-panel ("operator") access. A comma- or
# # whitespace-separated allowlist of GitHub logins, case-insensitive.
# # FAIL-CLOSED: unset/empty means NOBODY can sign into the dashboard,
Expand Down Expand Up @@ -258,7 +258,7 @@ LOOPOVER_REVIEW_DRAFT=false
# # default) is fine for a small/idle instance; raise it if you
# # register many repos or run higher QUEUE_CONCURRENCY, and you see
# # request/job latency climb without Postgres itself under pressure
# # (check GittensoryPostgresConnectionPressure and the app's own
# # (check LoopoverPostgresConnectionPressure and the app's own
# # request-latency metrics to tell those two cases apart).
REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review runtime. The default compose stack
# # starts Redis automatically; override for an external Redis.
Expand Down Expand Up @@ -317,7 +317,7 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review
# REVIEW_AUDIT_S3_PUBLIC_URL= # the bucket's own public base URL (an R2 public r2.dev bucket
# # URL, or a custom domain connected to the bucket) -- when set,
# # screenshots link DIRECTLY at this URL instead of proxying
# # through this instance's own /gittensory/shot route. Strongly
# # through this instance's own /loopover/shot route. Strongly
# # recommended alongside the bucket vars above; without it,
# # screenshots are stored in the bucket but still served through
# # this instance (same reachability requirement as REVIEW_AUDIT_DIR).
Expand Down Expand Up @@ -401,7 +401,7 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review
# --- MinIO S3-compatible object storage (--profile storage) ---
# MINIO_ROOT_USER=minio # REQUIRED when using --profile storage
# MINIO_ROOT_PASSWORD=changeme # REQUIRED when using --profile storage
# MINIO_BUCKET=gittensory # default bucket name (create via console at http://localhost:9001)
# MINIO_BUCKET=loopover # default bucket name (create via console at http://localhost:9001)
# MINIO_MEM_LIMIT=1g
# Console at http://localhost:9001
# S3 API at http://minio:9000 (from other containers) or http://localhost:9000 (from host)
Expand Down Expand Up @@ -491,7 +491,7 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review
# GITHUB_INSTALLATION_CONCURRENCY_DEFER_MS=15000 # base defer duration on denial, before jitter (15s)

# --- Caddy HTTPS terminator (#1203; requires --profile caddy) ---
# DOMAIN=gittensory.example.com # fully-qualified domain; Caddy auto-obtains a Let's Encrypt cert
# DOMAIN=loopover.example.com # fully-qualified domain; Caddy auto-obtains a Let's Encrypt cert

# --- Tailscale sidecar (#1204; requires --profile tailscale) ---
# Blank is valid until --profile tailscale is enabled.
Expand All @@ -500,7 +500,7 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review

# --- Self-hosted GitHub Actions runner (#1205; requires --profile runners) ---
# NOT part of the default recommended stack -- it is an OPTIONAL profile. Pick a deployment mode:
# 1. App-only VPS (recommended default): gittensory + Postgres/Redis/Qdrant/observability, no runners here.
# 1. App-only VPS (recommended default): loopover + Postgres/Redis/Qdrant/observability, no runners here.
# Use GitHub-hosted CI for your own repos, or a separate runner host (below).
# 2. Separate runner host: run `--profile runners` on a DIFFERENT machine from the review stack. CI load
# never contends with the app for CPU/disk/network.
Expand Down Expand Up @@ -586,15 +586,16 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review
# # never prompts, diffs, tokens, or bodies.
# SENTRY_RELEASE= # custom images only: set this ONLY when you uploaded source maps for
# # the exact built bundle under this exact release id. Future official
# # images bake LOOPOVER_VERSION=gittensory-selfhost@<version>, so do
# # images bake LOOPOVER_VERSION=gittensory-selfhost@<version> (yes,
# # still that prefix -- see scripts/deploy-selfhost-prebuilt.sh), so do
# # not override SENTRY_RELEASE for those images.
# OTEL_METRIC_EXPORT_INTERVAL=10000 # ms between metric exports (default 10s here; CLI default is 60s)
# OTEL_METRICS_EXPORTER=otlp # metrics-side counterpart to OTEL_TRACES_EXPORTER; empty = no app metrics
# OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 # override only for an external collector
# OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf # wire protocol for the endpoint above (http/protobuf | grpc)
# OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative # cumulative is what Prometheus expects; change
# # only for a backend that requires delta temporality
# OTEL_SERVICE_NAME=gittensory-selfhost
# OTEL_SERVICE_NAME=loopover-selfhost
#
# Live upstream PR/issue census (the GitHub data source). Install is automatic (GF_INSTALL_PLUGINS); add the
# data source after Grafana is up with: ./scripts/setup-github-datasource.sh (reads GITHUB_TOKEN below).
Expand Down Expand Up @@ -756,9 +757,9 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review
# # changes nothing.
# AI_ADVISORY_API_KEY= # bearer credential for AI_ADVISORY_BASE_URL, if it requires one.

# --- Gittensory Orb (#1255; ALWAYS-ON fleet-calibration telemetry) ---
# --- LoopOver Orb (#1255; ALWAYS-ON fleet-calibration telemetry) ---
# TELEMETRY NOTICE: running this self-hosted image contributes anonymized gate-calibration data to
# gittensory's central collector. This is ON BY DEFAULT and has no opt-out flag — it is part of the
# loopover's central collector. This is ON BY DEFAULT and has no opt-out flag — it is part of the
# self-hosting contract: install the GitHub App, and your instance reports fleet-calibration signal so the
# gate can be tuned from real outcomes across all self-hosters. It activates automatically once your App is
# configured (no App = nothing is sent). There is NO separate Orb App and NO setup wizard.
Expand All @@ -767,7 +768,7 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review
# flag, a bucketed reason category, and cycle time. NEVER sent: repo/owner/PR names, commit SHAs, code,
# diffs, comments, or logins. Repo/PR identifiers are HMAC-anonymized with a DEDICATED, randomly-generated
# per-instance secret created once and stored in your instance's own database (never your App private key or
# webhook secret) — and the collector never holds it, so even gittensory (running the collector) can never
# webhook secret) — and the collector never holds it, so even loopover (running the collector) can never
# de-anonymize them.
# The export carries no shared key; the collector treats it as untrusted, rate-limited, aggregate-only data.
# ORB_AIR_GAP=false # air-gapped/OFFLINE deployments only: compute locally, never send
Expand Down
2 changes: 1 addition & 1 deletion .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
title = "Gittensory secret scanning"
title = "LoopOver secret scanning"

[extend]
useDefault = true
Expand Down
2 changes: 1 addition & 1 deletion .loopover-miner.yml.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ============================================================================
# .loopover-miner.yml - per-repo miner configuration (EXAMPLE)
# ============================================================================
# A repo owner drops this file in to tell an autonomous Gittensory miner what to
# A repo owner drops this file in to tell an autonomous LoopOver miner what to
# look for and how to behave when targeting their repo. It is the MINER-side
# analogue of `.loopover.yml` (the review-side focus manifest).
#
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ services:
# capabilities: [gpu]
# A device reservation only takes effect on container CREATION -- `docker compose restart ollama` reuses
# the existing container's already-baked-in config and will NOT pick it up, even after adding the file to
# COMPOSE_FILE. Confirmed in production (#gittensory-4327): the override existed for days while the
# COMPOSE_FILE. Confirmed in production (#4327): the override existed for days while the
# running container's `docker inspect --format '{{json .HostConfig.DeviceRequests}}'` stayed `null`, and
# `ollama ps` kept reporting 100% CPU. Use `docker compose up -d --force-recreate ollama` (or any change
# that forces a recreate) after adding or editing a device reservation, then re-check `ollama ps` for
Expand Down
2 changes: 1 addition & 1 deletion loki/loki-config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Grafana Loki — monolithic / single-binary config for gittensory self-host.
# Grafana Loki — monolithic / single-binary config for loopover self-host.
# Verified against Loki v3.7.x (latest stable, June 2026): TSDB store + schema v13,
# filesystem object store (no S3), compactor-driven retention, structured metadata on.
#
Expand Down
2 changes: 1 addition & 1 deletion orb-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "2.1.0",
"description": "Source of truth for the self-hostable gittensory-orb container image's target release version (ghcr.io/jsonbored/loopover-selfhost). Bumped by a maintainer when a feat/fix/breaking change since the last stable orb-v tag warrants moving to a new target version -- scripts/orb-release-core.mjs and .github/workflows/orb-beta-release.yml read this file to decide what version the next automated beta snapshot targets. Promoting a beta to a stable orb-vX.Y.Z release is still a manual `git tag` -- this manifest only drives the automated beta channel."
"description": "Source of truth for the self-hostable loopover-orb container image's target release version (ghcr.io/jsonbored/loopover-selfhost). Bumped by a maintainer when a feat/fix/breaking change since the last stable orb-v tag warrants moving to a new target version -- scripts/orb-release-core.mjs and .github/workflows/orb-beta-release.yml read this file to decide what version the next automated beta snapshot targets. Promoting a beta to a stable orb-vX.Y.Z release is still a manual `git tag` -- this manifest only drives the automated beta channel."
}
4 changes: 2 additions & 2 deletions promtail/promtail-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ scrape_configs:
values: ["com.docker.compose.project=${COMPOSE_PROJECT_NAME}"]

relabel_configs:
# Compose service name -> `service` label (e.g. gittensory, prometheus, loki).
# Compose service name -> `service` label (e.g. loopover, prometheus, loki).
- source_labels: ["__meta_docker_container_label_com_docker_compose_service"]
target_label: "service"
# Compose project -> `compose_project` label.
Expand All @@ -57,7 +57,7 @@ scrape_configs:
replacement: "docker"

pipeline_stages:
# gittensory logs are JSON lines; every line has an "event" field, and only
# loopover logs are JSON lines; every line has an "event" field, and only
# error/warn lines set "level". Non-JSON lines (other images) fall through
# untouched because json.expressions on a non-JSON line yields empty values.
- json:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { describe, expect, it } from "vitest";
import enginePkg from "../../packages/loopover-engine/package.json";

// The gittensory-engine package is a packaging-only scaffold (no runtime logic yet — the barrel export is
// The loopover-engine package is a packaging-only scaffold (no runtime logic yet — the barrel export is
// intentionally empty until later issues extract deterministic modules into it). These tests pin the published
// package contract so the skeleton stays correct and installable as extraction lands.
describe("gittensory-engine package scaffold", () => {
describe("loopover-engine package scaffold", () => {
it("declares the published package identity", () => {
expect(enginePkg.name).toBe("@loopover/engine");
expect(enginePkg.version).toMatch(/^\d+\.\d+\.\d+$/);
Expand Down
2 changes: 1 addition & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default defineConfig({
environment: "node",
globals: true,
testTimeout: 15000,
// Retry a failed test once before failing the run. The gittensory gate auto-CLOSES a contributor PR
// Retry a failed test once before failing the run. The loopover gate auto-CLOSES a contributor PR
// on a red required CI, so a single transient flake must not kill an honest PR; a deterministic
// failure still fails both attempts (and vitest flags the retried test as flaky so it stays visible).
retry: 1,
Expand Down
Loading