diff --git a/.claude/skills/contributing-to-loopover/reference.md b/.claude/skills/contributing-to-loopover/reference.md index 5a23dda2cf..a370438d1b 100644 --- a/.claude/skills/contributing-to-loopover/reference.md +++ b/.claude/skills/contributing-to-loopover/reference.md @@ -17,7 +17,7 @@ for maintainer approval (CI shows unverified → the engine **holds**, never clo The single **required** status check is **`validate`** (it aggregates `changes, lint, test, workers, mcp, ui, security`; a path-skipped job counts as success). **Codecov** posts `codecov/patch` (the real coverage gate) and `codecov/project` (informational) independently. The review engine also posts its -own check run named **`LoopOver Orb Review Agent`** (`src/github/app.ts` `GITTENSORY_GATE_CHECK_NAME`) — the gate +own check run named **`LoopOver Orb Review Agent`** (`src/github/app.ts` `LOOPOVER_GATE_CHECK_NAME`) — the gate verdict (§3), separate from CI. On a PR, jobs run only if their path filter matched; on push to `main`, everything runs. @@ -188,7 +188,7 @@ own PR.) ```ts import { createTestEnv } from "../helpers/d1"; -const env = createTestEnv({ GITTENSORY_REVIEW_REPOS: "JSONbored/gittensory" }); +const env = createTestEnv({ LOOPOVER_REVIEW_REPOS: "JSONbored/gittensory" }); await env.DB.prepare(`INSERT INTO repositories (full_name, owner, name) VALUES (?,?,?)`) .bind("JSONbored/gittensory", "JSONbored", "gittensory").run(); const row = await env.DB.prepare(`SELECT * FROM repositories WHERE full_name = ?`) diff --git a/.env.example b/.env.example index 2ddf48f055..5f914452bb 100644 --- a/.env.example +++ b/.env.example @@ -165,8 +165,8 @@ LOOPOVER_REVIEW_DRAFT=false # TOKEN_ENCRYPTION_SECRET= # AES-256-GCM master secret for maintainer BYOK keys at rest # DRAFT_TOKEN_ENCRYPTION_SECRET= # AES-256-GCM secret for the contributor OAuth token (draft flow) # LOOPOVER_REVIEW_STATS_TOKEN= # bearer token guarding the stats data endpoint -# GITTENSORY_DRIFT_ISSUE_TOKEN= # token for auto-filing drift issues -# GITTENSORY_CONTRIBUTOR_ISSUE_TOKEN= # token for contributor-issue automation +# LOOPOVER_DRIFT_ISSUE_TOKEN= # token for auto-filing drift issues +# LOOPOVER_CONTRIBUTOR_ISSUE_TOKEN= # token for contributor-issue automation # PRODUCT_USAGE_HASH_SALT= # salt for hashing product-usage identifiers # ============================================================================= @@ -258,7 +258,7 @@ LOOPOVER_REVIEW_DRAFT=false # # 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. -# GITTENSORY_IMAGE=ghcr.io/jsonbored/loopover-selfhost:latest # image used by scripts/deploy-selfhost-image.sh; +# LOOPOVER_IMAGE=ghcr.io/jsonbored/loopover-selfhost:latest # image used by scripts/deploy-selfhost-image.sh; # # pin production rollouts to a release tag such as :orb-v0.1.0 # # or to an immutable @sha256 digest. # GITHUB_CACHE_TTL_SECONDS=20 # Enables the Redis-backed GitHub GET-response cache when >0; set 0 @@ -335,8 +335,8 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review # # benchmarking on an RTX A5000 found 96 already near-optimal # # (~34ms/chunk vs ~70ms/chunk at 32), so leave unset unless you # # have hardware-specific data suggesting otherwise. -# GITTENSORY_REPORTING_SOURCE_DATABASE_URL= # optional Postgres reporting reader URL. Defaults to DATABASE_URL. -# GITTENSORY_BACKUP_SOURCE_DATABASE_URL= # optional Postgres backup reader URL. Defaults to DATABASE_URL. +# LOOPOVER_REPORTING_SOURCE_DATABASE_URL= # optional Postgres reporting reader URL. Defaults to DATABASE_URL. +# LOOPOVER_BACKUP_SOURCE_DATABASE_URL= # optional Postgres backup reader URL. Defaults to DATABASE_URL. # MIGRATIONS_DIR=/app/migrations # CRON_INTERVAL_MS=120000 # maintain/sweep + sync cadence (default ~2 min) @@ -493,7 +493,7 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review # 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) +# LOOPOVER_DOCKER_PRUNE_RETAIN_HOURS=168 # age floor before something unused is eligible for pruning (7 days) # --- Observability: metrics + alerts + logs (#1206; requires --profile observability) --- # The observability profile starts Prometheus (scrapes /metrics) + Alertmanager (alert rules in diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a881e4e6cb..aca2e23366 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -169,7 +169,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 45 env: - VITE_GITTENSORY_API_ORIGIN: https://api.loopover.ai + VITE_LOOPOVER_API_ORIGIN: https://api.loopover.ai steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 @@ -422,7 +422,7 @@ jobs: matrix: shard: [1, 2, 3, 4, 5, 6] env: - VITE_GITTENSORY_API_ORIGIN: https://api.loopover.ai + VITE_LOOPOVER_API_ORIGIN: https://api.loopover.ai steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 diff --git a/.github/workflows/ui-deploy.yml b/.github/workflows/ui-deploy.yml index 4f8727fa95..f627ef07b7 100644 --- a/.github/workflows/ui-deploy.yml +++ b/.github/workflows/ui-deploy.yml @@ -36,5 +36,5 @@ jobs: # regen (mirrors the same fix in .github/workflows/ci.yml's "UI build" step). - name: Validate frontend env: - VITE_GITTENSORY_API_ORIGIN: https://api.loopover.ai + VITE_LOOPOVER_API_ORIGIN: https://api.loopover.ai run: npm run ui:openapi:check && npm run ui:lint && npm run ui:typecheck && npm run extension:lint && npm run miner-extension:lint && npm run extension:typecheck && npm run miner-extension:typecheck && npm run extension:build && npm run miner-extension:build && npm --workspace @loopover/ui run build diff --git a/.github/workflows/ui-preview-deploy.yml b/.github/workflows/ui-preview-deploy.yml index 05f0364d23..9d4e49508f 100644 --- a/.github/workflows/ui-preview-deploy.yml +++ b/.github/workflows/ui-preview-deploy.yml @@ -143,7 +143,7 @@ jobs: } }, "vars": { - "VITE_GITTENSORY_API_ORIGIN": "https://api.loopover.ai" + "VITE_LOOPOVER_API_ORIGIN": "https://api.loopover.ai" }, "main": "index.mjs", "assets": { diff --git a/.github/workflows/ui-preview.yml b/.github/workflows/ui-preview.yml index e989a876dc..d755fb8916 100644 --- a/.github/workflows/ui-preview.yml +++ b/.github/workflows/ui-preview.yml @@ -47,7 +47,7 @@ jobs: - name: Build UI env: - VITE_GITTENSORY_API_ORIGIN: https://api.loopover.ai + VITE_LOOPOVER_API_ORIGIN: https://api.loopover.ai # Preview-only: enables the synthetic demo session (useSession().signInPreview) so reviewbot can # screenshot the authenticated /app/* dashboard via ?preview=1 instead of the sign-in wall. The # production build (ui-deploy.yml) does NOT set this, so the escape hatch is dead-code-eliminated diff --git a/.loopover.yml.example b/.loopover.yml.example index a517a0362d..9d7ae80587 100644 --- a/.loopover.yml.example +++ b/.loopover.yml.example @@ -39,7 +39,7 @@ # # NOTE: some capabilities (safety scanning, CI/full-file grounding, RAG, # reputation control, the unified comment) are switched on at the deployment -# level by the operator's GITTENSORY_REVIEW_* feature flags AND a per-repo +# level by the operator's LOOPOVER_REVIEW_* feature flags AND a per-repo # cutover allowlist. This file tunes behavior; it does not enable those # deployment-wide capabilities. # ============================================================================ @@ -404,8 +404,8 @@ gate: # deterministic gate policy above. Omit the block to keep the byte-identical # defaults. # -# SELF-HOST ONLY (`review.shared_config`, #2046): when `GITTENSORY_REPO_CONFIG_DIR` is mounted, -# place a shared review base at `${GITTENSORY_REPO_CONFIG_DIR}/_shared/.loopover.yml` (see +# SELF-HOST ONLY (`review.shared_config`, #2046): when `LOOPOVER_REPO_CONFIG_DIR` is mounted, +# place a shared review base at `${LOOPOVER_REPO_CONFIG_DIR}/_shared/.loopover.yml` (see # `config/examples/shared.loopover.yml`). Per-repo `review:` keys overlay it field-by-field — # repo value wins when set, shared fills gaps, defaults stay byte-identical. Absent shared base is # the common case and changes nothing. A malformed shared base warns and is ignored (never blocks a @@ -472,7 +472,7 @@ review: # When true, the unified review comment gains a compact "review effort: N/5 (~M min)" chip. # Bool | null. Default: null/false — byte-identical (#2184, part of #1971). Also requires the operator's - # GITTENSORY_REVIEW_IMPACT_MAP env flag to be on — this manifest field alone cannot enable it. When both are + # LOOPOVER_REVIEW_IMPACT_MAP env flag to be on — this manifest field alone cannot enable it. When both are # on, a deterministic impact map (which other repo files plausibly need re-checking, from the RAG index + # changed symbols) is computed, rendered as a compact section in the unified review comment, and fed to the # AI reviewer as additive reference context. @@ -480,12 +480,12 @@ review: # When true, the AI reviewer's prompt gains an additive "repo quality-culture profile" reference block -- # typical merged-PR size + common accepted labels, derived from this repo's own merge history. Reference-only - # grounding; never a gate/scoring input. Requires operator flag GITTENSORY_REVIEW_CULTURE_PROFILE. Bool or + # grounding; never a gate/scoring input. Requires operator flag LOOPOVER_REVIEW_CULTURE_PROFILE. Bool or # null. Default: null/false — byte-identical. (#2995) # culture_profile: false # Per-repo FORCE-OFF for the self-improvement/auto-tune cron pass (#4104) -- `false` excludes this repo from - # tuning even though it's otherwise agent-configured and the operator's GITTENSORY_REVIEW_SELFTUNE flag is on. + # tuning even though it's otherwise agent-configured and the operator's LOOPOVER_REVIEW_SELFTUNE flag is on. # Deliberately FORCE-OFF-ONLY (no `true` override): unlike most `review.*` toggles above, this does NOT live # under a per-repo allowlist -- selftune's own scoping is whether the repo already opted into the # acting-autonomy surface, a separate consent boundary this key must not bypass. Bool or null. Default: @@ -493,7 +493,7 @@ review: # selftune: false # Repeat-false-positive suppression (#2179, part of #1964). Bool | null. Default: null/false — byte-identical - # (no suppression-store read, no matching). Also requires the operator's GITTENSORY_REVIEW_MEMORY env flag to + # (no suppression-store read, no matching). Also requires the operator's LOOPOVER_REVIEW_MEMORY env flag to # be on -- this manifest field alone cannot enable it. When both are on, an advisory (non-blocking) AI finding # is matched against this repo's stored review_suppression signals (a maintainer's own past false-positive # dismissals) before it is surfaced, and demoted/dropped on a match. ADVISORY-ONLY: never applied to gate @@ -534,7 +534,7 @@ review: # e2e_test_auto_trigger: false # Inline-comment layer toggles (#1956 / #1958). Bool | null. Default: null/false — byte-identical. - # Requires operator flag GITTENSORY_REVIEW_INLINE_COMMENTS + cutover allowlist + review.inline_comments: true. + # Requires operator flag LOOPOVER_REVIEW_INLINE_COMMENTS + cutover allowlist + review.inline_comments: true. # inline_comments: false # When true, the AI reviewer ALSO leaves quiet, non-blocking inline PR comments on specific changed lines. # suggestions: false @@ -543,7 +543,7 @@ review: # inline_comments_per_category: 3 # Fix-handoff blocks (#2176). Bool | null. Default: null/false — byte-identical. - # Requires operator flag GITTENSORY_REVIEW_FIX_HANDOFF + cutover allowlist AND this toggle. + # Requires operator flag LOOPOVER_REVIEW_FIX_HANDOFF + cutover allowlist AND this toggle. # fixHandoff: false # Read-only auto-merge readiness summary (#2051). Bool | null. Default: null/false — byte-identical. @@ -967,7 +967,7 @@ settings: # instructions: "Flag any migration missing a matching down-path note." # # When true, the AI reviewer ALSO leaves quiet, non-blocking inline PR comments on specific changed # # lines, in addition to the decision summary. Bool or null. Default: null/false (no inline comments). -# # Operator-gated too (GITTENSORY_REVIEW_INLINE_COMMENTS + allowlist). +# # Operator-gated too (LOOPOVER_REVIEW_INLINE_COMMENTS + allowlist). # inline_comments: false # # When true, an inline finding whose fix is precise enough to anchor to one line is ALSO rendered as # # a one-click GitHub suggestion block. Only takes effect when inline_comments is already on. Bool or @@ -981,7 +981,7 @@ settings: # # compact "review effort: N/5 (~M min)" chip -- a deterministic, no-AI complexity/time estimate from the # # changed files' added-line volume and file-type mix. Bool or null. Default: null/false. # effort_score: false -# # When true (AND the operator's GITTENSORY_REVIEW_IMPACT_MAP env flag is also on), a deterministic +# # When true (AND the operator's LOOPOVER_REVIEW_IMPACT_MAP env flag is also on), a deterministic # # impact map -- which other repo files plausibly need re-checking, from the RAG index + changed # # symbols -- is computed, rendered as a compact unified-comment section, and fed to the AI reviewer # # as additive reference context. Bool or null. Default: null/false (#2184, part of #1971). @@ -989,14 +989,14 @@ settings: # # When true, the AI reviewer's prompt gains an additive "repo quality-culture profile" reference block -- # # typical merged-PR size + common accepted labels, derived from this repo's OWN recent merge history # # (recent_merged_pull_requests). Reference-only grounding, never a gate/scoring input; requires the operator -# # flag GITTENSORY_REVIEW_CULTURE_PROFILE. Bool or null. Default: null/false. (#2995) +# # flag LOOPOVER_REVIEW_CULTURE_PROFILE. Bool or null. Default: null/false. (#2995) # culture_profile: false # # Per-repo FORCE-OFF for the self-improvement/auto-tune cron pass (#4104) -- false excludes this repo from # # tuning even though it's otherwise agent-configured and the operator flag is on. FORCE-OFF-ONLY, no true # # override -- selftune's own scoping is the acting-autonomy consent boundary, not a per-repo allowlist. Bool # # or null. Default: null/true -- no change to today's agent-configured-repos-only behavior. # selftune: false -# # When true (AND the operator's GITTENSORY_REVIEW_MEMORY env flag is also on), an advisory (non-blocking) +# # When true (AND the operator's LOOPOVER_REVIEW_MEMORY env flag is also on), an advisory (non-blocking) # # AI finding is matched against this repo's stored review_suppression signals (a maintainer's own past # # false-positive dismissals) before it is surfaced, and demoted/dropped on a match. ADVISORY-ONLY: never # # applied to gate blockers -- it can never change the merge/close disposition. Bool or null. @@ -1037,7 +1037,7 @@ settings: # openai_compatible_model: null # Overrides OPENAI_COMPATIBLE_AI_MODEL for this repo. String or null. (#3902) # anthropic_model: null # Overrides ANTHROPIC_AI_MODEL for this repo's BYOK Messages API reviewer. String or null. (#3902) # # Per-repo before/after screenshot-capture config (#3609 preview / #3610 routes). Only takes effect when -# # the operator has ALSO enabled GITTENSORY_REVIEW_SCREENSHOTS + this repo's cutover allowlist -- this +# # the operator has ALSO enabled LOOPOVER_REVIEW_SCREENSHOTS + this repo's cutover allowlist -- this # # config narrows/redirects that feature, it never turns it on by itself. All-null/empty/default ⇒ # # byte-identical to today (GitHub-native preview discovery, automatic file-to-route inference). # visual: @@ -1084,7 +1084,7 @@ settings: # # renders per side, ~4s wall-clock per side measured in practice. Bool. Default: false (no scroll capture). # gif: false # # Config-as-code enable/disable for this repo, layered ON TOP OF (never a replacement for) the -# # GITTENSORY_REVIEW_SCREENSHOTS + per-repo cutover-allowlist env-var gate above (#4083). Bool or null. +# # LOOPOVER_REVIEW_SCREENSHOTS + per-repo cutover-allowlist env-var gate above (#4083). Bool or null. # # Default: null (unset) ⇒ defers entirely to that env-var gate's own decision -- byte-identical to today. # # Explicit `false` (set once at the global-default `.loopover.yml`, or overridden per-repo here) forces # # capture off for this repo even when the env-var gate would otherwise allow it. Explicit `true` opts this @@ -1128,9 +1128,9 @@ settings: # auto_pause_after_reviewed_commits: 3 # Per-repo activation overrides for the converged review features that ship behind a deployment-wide -# GITTENSORY_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety/grounding/e2eTests/screenshots/ +# LOOPOVER_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety/grounding/e2eTests/screenshots/ # improvementSignal). Each key is `true` (force on for this repo, subject to the env flag still being -# enabled), `false` (force off), or omitted (falls back to the GITTENSORY_REVIEW_REPOS allowlist default -- +# enabled), `false` (force off), or omitted (falls back to the LOOPOVER_REVIEW_REPOS allowlist default -- # an operator who sets nothing keeps today's behavior). Exception: `safety` is force-on-only -- an untrusted # repo-controlled `false` is treated as "no opinion" rather than an active force-off (#2269), since a # lower-trust actor must never be able to silently defeat the operator's own security-hardening enablement. @@ -1158,8 +1158,8 @@ settings: # Optional ecosystem/network PLUGINS -- distinct from `features:` above, which only toggles gittensory's own # converged review capabilities. Each key here couples this instance to an external system and is OFF unless -# BOTH a deployment-wide GITTENSORY_EXPERIMENTAL_* env kill-switch AND an explicit per-repo `true` are set (no -# GITTENSORY_REVIEW_REPOS allowlist fallback -- unlike `features:`, there is no default-on path). `gittensor` +# BOTH a deployment-wide LOOPOVER_EXPERIMENTAL_* env kill-switch AND an explicit per-repo `true` are set (no +# LOOPOVER_REVIEW_REPOS allowlist fallback -- unlike `features:`, there is no default-on path). `gittensor` # is the first plugin: gittensory's original subnet mining-registry/scoring integration (per-repo emission # share, maintainer cut, label multipliers pulled from the gittensor subnet's registry), now opt-in rather # than a core dependency -- a self-host instance that never sets this has zero footprint from it: no fetch @@ -1206,7 +1206,7 @@ settings: # that folds gate-precision + outcome-calibration across every scanned repo into one report (distinct from # the single-repo reviewRecap above). Operator-level, not per-repo -- only meaningful on the gittensory # self-repo's own manifest (the repo this instance identifies as); a present block there wins over the -# GITTENSORY_MAINTAINER_RECAP / GITTENSORY_RECAP_CADENCE env vars, which stay the fallback when absent. +# LOOPOVER_MAINTAINER_RECAP / LOOPOVER_RECAP_CADENCE env vars, which stay the fallback when absent. # maintainerRecap: # enabled: true # Bool. Default: false (env vars decide instead). # cadence: weekly # daily | weekly. Default: weekly. Invalid values fall back to weekly. diff --git a/CHANGELOG.md b/CHANGELOG.md index 622d03adb1..f05711fb80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,7 +65,7 @@ - Render the public PR feedback as one unified review comment -- Gate per-PR review capabilities behind per-repo activation (GITTENSORY_REVIEW_* flags) +- Gate per-PR review capabilities behind per-repo activation (LOOPOVER_REVIEW_* flags) diff --git a/CONVERGENCE_RUNBOOK.md b/CONVERGENCE_RUNBOOK.md index 9dba2999c9..65fbb62f54 100644 --- a/CONVERGENCE_RUNBOOK.md +++ b/CONVERGENCE_RUNBOOK.md @@ -15,15 +15,15 @@ This runbook records the **post-port** operating model for the reviewbot → git - `#982` — dashboard / observability - `#1030` — decommission legacy reviewbot identity + repo, keep gittensory as the single project -The old vendor/embed plan is obsolete. The review system now lives in **gittensory-native codepaths** guarded by `GITTENSORY_REVIEW_*` flags. There is no `REVIEWBOT_ENGINE_ENABLED` path in this repository. +The old vendor/embed plan is obsolete. The review system now lives in **gittensory-native codepaths** guarded by `LOOPOVER_REVIEW_*` flags. There is no `REVIEWBOT_ENGINE_ENABLED` path in this repository. ## Current architecture - **Single project:** gittensory is the only source repo for the converged review system. - **Native port:** review features live under `src/review/**`, `src/queue/processors.ts`, and related first-party modules. -- **Public comment path:** the unified in-place PR comment is driven by the native bridge and the `GITTENSORY_REVIEW_UNIFIED_COMMENT` flag. +- **Public comment path:** the unified in-place PR comment is driven by the native bridge and the `LOOPOVER_REVIEW_UNIFIED_COMMENT` flag. - **Infra model:** D1 / Queue / AI / optional Vectorize / optional R2 / optional Browser bindings are declared directly in gittensory. -- **Config model:** rollout is controlled by `GITTENSORY_REVIEW_*` flags plus the per-repo allowlist `GITTENSORY_REVIEW_REPOS`. +- **Config model:** rollout is controlled by `LOOPOVER_REVIEW_*` flags plus the per-repo allowlist `LOOPOVER_REVIEW_REPOS`. - **Parity model:** parity is measured as a shadow/deploy-time comparison against authoritative legacy audit rows; local checkout validation proves structure and safety, not historical decision identity. ## What issue `#1030` means in this repo @@ -48,15 +48,15 @@ Those are operator actions. This repo should document them clearly and avoid imp Primary native review flags and surfaces: -- `GITTENSORY_REVIEW_UNIFIED_COMMENT` — single public PR comment -- `GITTENSORY_REVIEW_SAFETY` — prompt-injection defang + secret scan -- `GITTENSORY_REVIEW_GROUNDING` — CI + full-file grounding -- `GITTENSORY_REVIEW_RAG` — retrieval-augmented context -- `GITTENSORY_REVIEW_REPUTATION` — internal spend gate -- `GITTENSORY_REVIEW_OPS` — operator stats / anomaly surfaces -- `GITTENSORY_REVIEW_SELFTUNE` — tightening-only self-tuning loop -- `GITTENSORY_REVIEW_PARITY_AUDIT` — shadow parity recording -- `GITTENSORY_REVIEW_REPOS` — per-repo cutover allowlist +- `LOOPOVER_REVIEW_UNIFIED_COMMENT` — single public PR comment +- `LOOPOVER_REVIEW_SAFETY` — prompt-injection defang + secret scan +- `LOOPOVER_REVIEW_GROUNDING` — CI + full-file grounding +- `LOOPOVER_REVIEW_RAG` — retrieval-augmented context +- `LOOPOVER_REVIEW_REPUTATION` — internal spend gate +- `LOOPOVER_REVIEW_OPS` — operator stats / anomaly surfaces +- `LOOPOVER_REVIEW_SELFTUNE` — tightening-only self-tuning loop +- `LOOPOVER_REVIEW_PARITY_AUDIT` — shadow parity recording +- `LOOPOVER_REVIEW_REPOS` — per-repo cutover allowlist These replace the old notion of a separate reviewbot engine toggle. diff --git a/README.md b/README.md index 044a68072f..3140347abe 100644 --- a/README.md +++ b/README.md @@ -31,20 +31,20 @@ See [Privacy and security](https://gittensory.aethereal.dev/docs/privacy-securit ## Review Capabilities -LoopOver CI and LoopOver review score, gate, and comment on pull requests. The review algorithm is open-source; operators tune behavior through per-repo settings and the `GITTENSORY_REVIEW_*` feature flags, every one of which ships **OFF** and is opt-in per repo. +LoopOver CI and LoopOver review score, gate, and comment on pull requests. The review algorithm is open-source; operators tune behavior through per-repo settings and the `LOOPOVER_REVIEW_*` feature flags, every one of which ships **OFF** and is opt-in per repo. - **Safety scan** — defangs untrusted PR title/body/diff (prompt-injection neutralization) before the AI reviewer reads them, and scans the diff for leaked secrets, surfacing a `secret_leak` blocker. - **CI + full-file grounding** — grounds the AI reviewer with the PR's finished CI status and the full post-change content of the changed files, so claims are verified against reality instead of predicted. - **Codebase RAG** — retrieval-augmented context that queries the codebase vector index for related callers, modules, and conventions and appends them to the reviewer prompt (additive only; inert until an index exists). - **Submitter-reputation gating** — an internal-only spend control that downgrades new / burst / low-reputation submitters to a deterministic-only review, never surfaced on any public comment, label, or check. - **Unified review comment** — renders the public PR feedback as one in-place comment instead of multiple panels. With `.loopover.yml`'s `review.changed_files_summary` also on (off by default), it gains a deterministic, no-AI "Changed files" collapsible: one row per file category (source/test/docs/config/generated), with file counts and +/- totals. -- **Per-repo activation** — capabilities roll forward (and back) one flag and one repo at a time via the `GITTENSORY_REVIEW_REPOS` allowlist. +- **Per-repo activation** — capabilities roll forward (and back) one flag and one repo at a time via the `LOOPOVER_REVIEW_REPOS` allowlist. **Check-run and comment surfaces, disambiguated** (a common point of confusion — these are three independent, separately-configured things, not layers of the same feature): - **`LoopOver Orb Review Agent`** (`gate.*` / `settings.reviewCheckMode`, off by default) — the authoritative GitHub Check Run carrying the gate's pass/fail verdict. This is the one worth making a required status check. - **`LoopOver Context`** (`settings.checkRunMode` / `settings.checkRunDetailLevel`, off by default) — a separate, purely advisory Check Run. At its default `checkRunDetailLevel: minimal` it publishes no findings at all; even at `standard`/`deep` it only re-renders content already shown elsewhere. Never make this one required. -- **Inline review comments** (`GITTENSORY_REVIEW_INLINE_COMMENTS` + `.loopover.yml`'s `review.inline_comments`, off by both by default) — real, reply-able line-anchored PR review comment threads (CodeRabbit-style). This is the ONLY one of the three that posts an interactive per-line thread; the two check runs above never do. With `.loopover.yml`'s `review.suggestions` also on, a precise line-anchored fix is additionally rendered as a one-click, committable GitHub suggested-change block. With `review.finding_categories` also on (off by default), each finding is additionally tagged with a category — security/correctness/performance/maintainability/tests/style — in both the inline comment label and the unified comment's "Finding categories" collapsible; a deterministic path/keyword fallback covers whatever the model omits. +- **Inline review comments** (`LOOPOVER_REVIEW_INLINE_COMMENTS` + `.loopover.yml`'s `review.inline_comments`, off by both by default) — real, reply-able line-anchored PR review comment threads (CodeRabbit-style). This is the ONLY one of the three that posts an interactive per-line thread; the two check runs above never do. With `.loopover.yml`'s `review.suggestions` also on, a precise line-anchored fix is additionally rendered as a one-click, committable GitHub suggested-change block. With `review.finding_categories` also on (off by default), each finding is additionally tagged with a category — security/correctness/performance/maintainability/tests/style — in both the inline comment label and the unified comment's "Finding categories" collapsible; a deterministic path/keyword fallback covers whatever the model omits. See [Tuning your reviews](https://gittensory.aethereal.dev/docs/tuning) for the full flag, setting, and `.loopover.yml` reference. diff --git a/apps/loopover-extension/auth.js b/apps/loopover-extension/auth.js index b4913736ac..2e72b3dfa1 100644 --- a/apps/loopover-extension/auth.js +++ b/apps/loopover-extension/auth.js @@ -20,7 +20,7 @@ const LOCAL_SESSION_KEYS = [ ]; const GITHUB_TOKEN_PREFIX_PATTERN = /^(ghp|gho|ghu|ghs|ghr|github_pat)_/i; -const GITTENSORY_SESSION_PATTERN = /^gts_[a-f0-9]{64}$/i; +const LOOPOVER_SESSION_PATTERN = /^gts_[a-f0-9]{64}$/i; export function extensionStorage(chromeLike = globalThis.chrome) { if (!chromeLike?.storage?.local || !chromeLike?.storage?.sync) { @@ -52,7 +52,7 @@ export function validateExtensionSessionToken(value) { if (looksLikeGitHubPersonalAccessToken(token)) { throw new Error("GitHub personal access tokens are not accepted. Create a LoopOver extension token instead."); } - if (!GITTENSORY_SESSION_PATTERN.test(token)) { + if (!LOOPOVER_SESSION_PATTERN.test(token)) { throw new Error("Extension tokens must be LoopOver session tokens that start with gts_."); } return token; diff --git a/apps/loopover-extension/content.js b/apps/loopover-extension/content.js index c0a35ff110..acb8734920 100644 --- a/apps/loopover-extension/content.js +++ b/apps/loopover-extension/content.js @@ -23,7 +23,7 @@ function mountOverlay(target) { const container = document.createElement("aside"); const host = findPullRequestSidebar(); container.className = `gittensory-overlay ${host ? "gittensory-overlay--sidebar" : "gittensory-overlay--floating"}`; - container.dataset.gittensoryPrContext = "true"; + container.dataset.loopoverPrContext = "true"; container.innerHTML = `
G @@ -181,7 +181,7 @@ function renderActions(body, actions) { body.appendChild(container); } -if (globalThis.__GITTENSORY_EXTENSION_TEST__) { +if (globalThis.__LOOPOVER_EXTENSION_TEST__) { globalThis.__gittensoryContentInternals = { matchGitHubPageTarget, matchPullRequestTarget, diff --git a/apps/loopover-miner-extension/content.js b/apps/loopover-miner-extension/content.js index 064bfbbf93..00c32e812d 100644 --- a/apps/loopover-miner-extension/content.js +++ b/apps/loopover-miner-extension/content.js @@ -20,7 +20,7 @@ function mountOpportunityBadge(target) { container.className = host ? "gittensory-miner-opportunity-badge" : "gittensory-miner-opportunity-badge gittensory-miner-opportunity-badge--floating"; - container.dataset.gittensoryMinerOpportunityBadge = "true"; + container.dataset.loopoverMinerOpportunityBadge = "true"; container.hidden = true; if (host) { host.prepend(container); diff --git a/apps/loopover-ui/public/openapi.json b/apps/loopover-ui/public/openapi.json index 6ca2defd8c..8d1ffc2e0a 100644 --- a/apps/loopover-ui/public/openapi.json +++ b/apps/loopover-ui/public/openapi.json @@ -13955,7 +13955,7 @@ } }, "404": { - "description": "Public stats are disabled (GITTENSORY_PUBLIC_STATS off)" + "description": "Public stats are disabled (LOOPOVER_PUBLIC_STATS off)" }, "503": { "description": "Public stats are temporarily unavailable" diff --git a/apps/loopover-ui/src/components/site/proof-of-power-stats.tsx b/apps/loopover-ui/src/components/site/proof-of-power-stats.tsx index 8d4be3684c..728c08c7c0 100644 --- a/apps/loopover-ui/src/components/site/proof-of-power-stats.tsx +++ b/apps/loopover-ui/src/components/site/proof-of-power-stats.tsx @@ -14,7 +14,7 @@ import { } from "@/components/site/proof-of-power-stats-model"; // Proof of Power (#1059): the above-the-fold homepage stats band. Polls the public, unauthenticated -// /v1/public/stats endpoint every 60s. The endpoint 404s until GITTENSORY_PUBLIC_STATS is enabled, so until then +// /v1/public/stats endpoint every 60s. The endpoint 404s until LOOPOVER_PUBLIC_STATS is enabled, so until then // (or on any failure) this renders NOTHING — the homepage is byte-identical to today. Counts only; no PR content. const intFmt = new Intl.NumberFormat("en"); diff --git a/apps/loopover-ui/src/lib/api/origin.ts b/apps/loopover-ui/src/lib/api/origin.ts index 876f1f8a15..127b0867a5 100644 --- a/apps/loopover-ui/src/lib/api/origin.ts +++ b/apps/loopover-ui/src/lib/api/origin.ts @@ -1,7 +1,7 @@ const DEFAULT_API_ORIGIN = "https://api.loopover.ai"; export function getApiOrigin(): string { - const configured = import.meta.env.VITE_GITTENSORY_API_ORIGIN?.trim(); + const configured = import.meta.env.VITE_LOOPOVER_API_ORIGIN?.trim(); const origin = configured || DEFAULT_API_ORIGIN; return origin.replace(/\/+$/, ""); } diff --git a/apps/loopover-ui/src/lib/openapi.ts b/apps/loopover-ui/src/lib/openapi.ts index 7834dbf66b..50a781d533 100644 --- a/apps/loopover-ui/src/lib/openapi.ts +++ b/apps/loopover-ui/src/lib/openapi.ts @@ -185,7 +185,7 @@ export function generateCurl(op: OpenApiOperation, server: string, token?: strin const url = server.replace(/\/$/, "") + op.path; const lines = [`curl -X ${op.method.toUpperCase()} '${url}' \\`]; if (op.requiresAuth) { - lines.push(` -H 'Authorization: Bearer ${token ? token : "$GITTENSORY_TOKEN"}' \\`); + lines.push(` -H 'Authorization: Bearer ${token ? token : "$LOOPOVER_TOKEN"}' \\`); } lines.push(` -H 'Accept: application/json'`); if (op.method !== "get" && op.method !== "delete") { diff --git a/apps/loopover-ui/src/routes/docs.miner-quickstart.tsx b/apps/loopover-ui/src/routes/docs.miner-quickstart.tsx index 183f0ea76d..bbfbf63e97 100644 --- a/apps/loopover-ui/src/routes/docs.miner-quickstart.tsx +++ b/apps/loopover-ui/src/routes/docs.miner-quickstart.tsx @@ -69,7 +69,7 @@ gittensory-mcp doctor --json`} /> Session tokens are LoopOver tokens backed by GitHub identity, not your - GitHub PATs. Source upload stays disabled (GITTENSORY_UPLOAD_SOURCE=false) and + GitHub PATs. Source upload stays disabled (LOOPOVER_UPLOAD_SOURCE=false) and local absolute paths are redacted from anything that leaves your machine. Log out anytime with gittensory-mcp logout. diff --git a/apps/loopover-ui/src/routes/docs.self-hosting-backup-scaling.tsx b/apps/loopover-ui/src/routes/docs.self-hosting-backup-scaling.tsx index 53ddeab002..c8061aad3e 100644 --- a/apps/loopover-ui/src/routes/docs.self-hosting-backup-scaling.tsx +++ b/apps/loopover-ui/src/routes/docs.self-hosting-backup-scaling.tsx @@ -172,12 +172,12 @@ docker compose --profile backup run --rm backup sh /scripts/verify-backup.sh /ba lang="bash" code={`docker compose --profile backup run --rm \\ -e VERIFY_RESTORE_SCRATCH=1 \\ - -e GITTENSORY_VERIFY_SCRATCH_DATABASE_URL=postgres://user:pass@host:5432/loopover_verify \\ + -e LOOPOVER_VERIFY_SCRATCH_DATABASE_URL=postgres://user:pass@host:5432/loopover_verify \\ backup sh /scripts/verify-backup.sh`} /> The scratch restore runs pg_restore --clean against{" "} - GITTENSORY_VERIFY_SCRATCH_DATABASE_URL, so point it at a dedicated database you + LOOPOVER_VERIFY_SCRATCH_DATABASE_URL, so point it at a dedicated database you can afford to drop. The script refuses to run when that URL equals the live backup source. diff --git a/apps/loopover-ui/src/routes/docs.self-hosting-operations.tsx b/apps/loopover-ui/src/routes/docs.self-hosting-operations.tsx index 1e9e5aa89f..b5c9b9ac80 100644 --- a/apps/loopover-ui/src/routes/docs.self-hosting-operations.tsx +++ b/apps/loopover-ui/src/routes/docs.self-hosting-operations.tsx @@ -933,7 +933,7 @@ SENTRY_ORG_SLUG=