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
7 changes: 1 addition & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# --- Scope (per-repo cutover allowlist) -------------------------------------

# Comma-separated owner/repo names allowed to run the per-PR review features
# (SAFETY, GROUNDING, RAG, REPUTATION, UNIFIED_COMMENT). A per-PR feature runs on
# (SAFETY, GROUNDING, RAG, REPUTATION). A per-PR feature runs on
# 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.
Expand Down Expand Up @@ -107,11 +107,6 @@ LOOPOVER_REVIEW_ENRICHMENT=false
LOOPOVER_REVIEW_REPUTATION=false
# GITTENSORY_REVIEW_REPUTATION=false # no longer read (removed by #4777)

# Renders the public PR comment as one in-place unified comment instead of the
# legacy multi-panel comment. OFF keeps the legacy comment byte-identical.
LOOPOVER_REVIEW_UNIFIED_COMMENT=false
# GITTENSORY_REVIEW_UNIFIED_COMMENT=false # no longer read (removed by #4777)

# --- Global capabilities (NOT scoped by LOOPOVER_REVIEW_REPOS) -------------

# Observability (read-only): cron anomaly scan over the gate-block ledger emits
Expand Down
2 changes: 0 additions & 2 deletions .env.selfhost.example
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ REDIS_URL=redis://redis:6379
SELFHOST_DEPLOYMENT_MODE=dry-run
LOOPOVER_REVIEW_REPOS=owner/repo
# GITTENSORY_REVIEW_REPOS=owner/repo # no longer read (removed by #4777)
LOOPOVER_REVIEW_UNIFIED_COMMENT=true
# GITTENSORY_REVIEW_UNIFIED_COMMENT=true # no longer read (removed by #4777)
LOOPOVER_REVIEW_SAFETY=true
# GITTENSORY_REVIEW_SAFETY=true # no longer read (removed by #4777)
LOOPOVER_REVIEW_GROUNDING=true
Expand Down
6 changes: 2 additions & 4 deletions .loopover.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,6 @@ review:
# max_files: 25

# Unified-comment display toggles (#1957 / #1955 / #2069). Bool | null. Default: null/false — byte-identical.
# Only take effect when the `features.unifiedComment` feature is enabled.
# changed_files_summary: false
# When true, the unified review comment gains a deterministic "Changed files" summary table.
# effort_score: false
Expand Down Expand Up @@ -1120,7 +1119,7 @@ settings:
# intentRouting: false # Closed-set intent classifier for unrecognized @loopover mentions -> existing Q&A commands only. Ollama-ONLY, same as chatQa (never uses chatQaFrontierFallback). Co-requisite: commandRateLimitPolicy: hold. Default: false.

# Per-repo activation overrides for the converged review features that ship behind a deployment-wide
# LOOPOVER_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety/grounding/e2eTests/screenshots/
# LOOPOVER_REVIEW_* env kill-switch (rag/reputation/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 LOOPOVER_REVIEW_REPOS allowlist default --
# an operator who sets nothing keeps today's behavior). Exception: `safety` is force-on-only -- an untrusted
Expand All @@ -1134,14 +1133,13 @@ settings:
# `review.visual.enabled: false` as an always-available additional force-off); this key only answers "does
# capture run for this repo at all," the same question its siblings answer for their own feature.
# `e2eTests` (#4190) and `improvementSignal` (#4738, foundation phase of the #4737 PR-improvement-signal
# epic) remain plain symmetric overrides like rag/reputation/unifiedComment -- neither carries a
# epic) remain plain symmetric overrides like rag/reputation -- neither carries a
# security-hardening or full-file-fetch rationale that would justify a force-on/force-off asymmetry.
# `improvementSignal` is activation wiring only for now -- no tier reads the resolved
# value yet.
# features:
# rag: true
# reputation: false
# unifiedComment: true
# safety: true
# grounding: true
# e2eTests: false
Expand Down
3 changes: 1 addition & 2 deletions CONVERGENCE_RUNBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The old vendor/embed plan is obsolete. The review system now lives in **gittenso

- **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 `LOOPOVER_REVIEW_UNIFIED_COMMENT` flag.
- **Public comment path:** the unified in-place PR comment is rendered unconditionally by the native bridge — it is the only comment-rendering path (the legacy multi-panel renderer and its `LOOPOVER_REVIEW_UNIFIED_COMMENT` flag were retired).
- **Infra model:** D1 / Queue / AI / optional Vectorize / optional R2 / optional Browser bindings are declared directly in gittensory.
- **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.
Expand All @@ -48,7 +48,6 @@ Those are operator actions. This repo should document them clearly and avoid imp

Primary native review flags and surfaces:

- `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
Expand Down
9 changes: 2 additions & 7 deletions apps/loopover-ui/src/routes/docs.github-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,6 @@ review:
new / burst / low-reputation submitter to a deterministic-only review. Internal-only,
never surfaced publicly. Per-PR.
</li>
<li>
<code>LOOPOVER_REVIEW_UNIFIED_COMMENT</code> — renders the public PR comment as one
in-place unified comment instead of the legacy multi-panel comment. Per-PR; flag-off keeps
the legacy comment byte-identical.
</li>
<li>
<code>LOOPOVER_REVIEW_OPS</code> — read-only observability: a cron anomaly scan over your
own review-outcome data plus a bearer-gated stats aggregate. Global (not scoped by the
Expand Down Expand Up @@ -338,9 +333,9 @@ review:
</p>
<CodeBlock
lang="bash"
code={`# Roll grounding + the unified comment onto one repo:
code={`# Roll grounding + RAG context onto one repo:
LOOPOVER_REVIEW_GROUNDING="true"
LOOPOVER_REVIEW_UNIFIED_COMMENT="true"
LOOPOVER_REVIEW_RAG="true"
LOOPOVER_REVIEW_REPOS="JSONbored/loopover"`}
/>

Expand Down
22 changes: 13 additions & 9 deletions apps/loopover-ui/src/routes/docs.how-reviews-work.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,7 @@ function HowReviewsWork() {
<h2>3. The unified review comment</h2>
<p>
The result is rendered as <strong>one in-place comment</strong> on the PR — updated in place
on each push rather than stacked — when <code>LOOPOVER_REVIEW_UNIFIED_COMMENT</code> is on
for the repo. It has three parts, top to bottom:
on each push rather than stacked. It has three parts, top to bottom:
</p>
<ul>
<li>
Expand All @@ -240,14 +239,16 @@ function HowReviewsWork() {
scans first.
</li>
<li>
<strong>The signal table</strong> — a compact row-per-signal summary: each dimension that
ran, its state (pass / advisory / block), and a short reason. This is the at-a-glance map
of why the verdict came out the way it did.
<strong>Decision drivers</strong> — a short, always-visible checklist of the signals that
actually decided the verdict: the AI code review and the gate result. This is the
at-a-glance answer to why the verdict came out the way it did.
</li>
<li>
<strong>Collapsibles</strong> — expandable sections for the detail behind each signal: the
AI review notes, the slop warnings, duplicate matches, manifest findings. Folded away by
default so the comment stays short, opened when a reader wants the evidence.
<strong>Collapsibles</strong> — expandable sections for everything else: a "Context &amp;
advisory signals" table (linked issue, related work, validation posture, contributor
context — signals that inform but never block the verdict), the AI review notes, slop
warnings, duplicate matches, manifest findings. Folded away by default so the comment
stays short, opened when a reader wants the evidence.
</li>
</ul>
<p>
Expand All @@ -265,7 +266,10 @@ function HowReviewsWork() {
</Callout>

<h2>4. The signals behind a verdict</h2>
<p>Each row in the signal table comes from a named finding. The common ones you will see:</p>
<p>
Each row in the advisory signals table comes from a named finding. The common ones you will
see:
</p>
<ul>
<li>
<code>secret_leak</code> — the safety scan (<code>LOOPOVER_REVIEW_SAFETY</code>) found a
Expand Down
1 change: 0 additions & 1 deletion apps/loopover-ui/src/routes/docs.privacy-security.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ LOOPOVER_REVIEW_IMPACT_MAP="true" # deterministic impact map (needs
LOOPOVER_REVIEW_CULTURE_PROFILE="true" # repo quality-culture profile (needs review.culture_profile: true)
LOOPOVER_REVIEW_MEMORY="true" # repeat-false-positive suppression (needs review.memory too)
LOOPOVER_REVIEW_REPUTATION="true" # submitter-reputation spend control (never shown)
LOOPOVER_REVIEW_UNIFIED_COMMENT="true" # one in-place unified PR comment
LOOPOVER_REVIEW_ENRICHMENT="true" # external analyzer registry (REES) findings
LOOPOVER_REVIEW_INLINE_COMMENTS="true" # diff-anchored inline PR review comments
LOOPOVER_REVIEW_FIX_HANDOFF="true" # machine-readable fix-handoff block (contributor-run)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,6 @@ GITHUB_METADATA_CACHE_TTL_SECONDS=600`}
<CodeBlock
filename=".env"
code={`LOOPOVER_REVIEW_REPOS=owner/repo,owner/another
LOOPOVER_REVIEW_UNIFIED_COMMENT=true
LOOPOVER_REVIEW_INLINE_COMMENTS=false
LOOPOVER_REVIEW_SAFETY=true
LOOPOVER_REVIEW_GROUNDING=true
Expand Down Expand Up @@ -481,17 +480,16 @@ settings:
agentDryRun: false
features:
safety: true
unifiedComment: true
rag: false
reputation: false`}
/>
<p>
The <code>features:</code> block above overrides a deployment-wide{" "}
<code>LOOPOVER_REVIEW_*</code> flag (rag, reputation, unifiedComment, safety) for this one
repo, with three states per key: <code>true</code> forces the capability on for this repo
(still subject to the env flag itself being enabled — it can never turn on a capability the
operator has fully disabled at the deployment level); <code>false</code> forces it off for
this repo regardless of the env flag; and omitting the key entirely falls back to the{" "}
<code>LOOPOVER_REVIEW_*</code> flag (rag, reputation, safety) for this one repo, with three
states per key: <code>true</code> forces the capability on for this repo (still subject to
the env flag itself being enabled — it can never turn on a capability the operator has fully
disabled at the deployment level); <code>false</code> forces it off for this repo regardless
of the env flag; and omitting the key entirely falls back to the{" "}
<code>LOOPOVER_REVIEW_REPOS</code> allowlist default, i.e. today's behavior for an operator
who hasn't set anything here. See <Link to="/docs/tuning">Tuning your reviews</Link> for the
full <code>LOOPOVER_REVIEW_*</code> flag list this overrides.
Expand Down
5 changes: 0 additions & 5 deletions apps/loopover-ui/src/routes/docs.tuning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,6 @@ function Tuning() {
reputation proceeds normally. Never surfaced publicly — no comment, label, or check shows
reputation. Per-PR.
</li>
<li>
<code>LOOPOVER_REVIEW_UNIFIED_COMMENT</code> — renders the public PR comment as one
in-place unified comment instead of the legacy multi-panel comment. Per-PR. With the flag
off, the legacy comment is byte-identical.
</li>
<li>
<code>LOOPOVER_REVIEW_ENRICHMENT</code> — runs the review-enrichment analyzer registry
(duplication, churn hotspots, blame links, approval integrity, undocumented exports, and
Expand Down
6 changes: 2 additions & 4 deletions config/examples/loopover.full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,6 @@ review:
# max_files: 25

# Unified-comment display toggles (#1957 / #1955 / #2069). Bool | null. Default: null/false — byte-identical.
# Only take effect when the `features.unifiedComment` feature is enabled.
# changed_files_summary: false
# When true, the unified review comment gains a deterministic "Changed files" summary table.
# effort_score: false
Expand Down Expand Up @@ -1134,7 +1133,7 @@ settings:
# intentRouting: false # Closed-set intent classifier for unrecognized @loopover mentions -> existing Q&A commands only. Ollama-ONLY, same as chatQa (never uses chatQaFrontierFallback). Co-requisite: commandRateLimitPolicy: hold. Default: false.

# Per-repo activation overrides for the converged review features that ship behind a deployment-wide
# LOOPOVER_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety/grounding/e2eTests/screenshots/
# LOOPOVER_REVIEW_* env kill-switch (rag/reputation/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 LOOPOVER_REVIEW_REPOS allowlist default --
# an operator who sets nothing keeps today's behavior). Exception: `safety` is force-on-only -- an untrusted
Expand All @@ -1148,14 +1147,13 @@ settings:
# `review.visual.enabled: false` as an always-available additional force-off); this key only answers "does
# capture run for this repo at all," the same question its siblings answer for their own feature.
# `e2eTests` (#4190) and `improvementSignal` (#4738, foundation phase of the #4737 PR-improvement-signal
# epic) remain plain symmetric overrides like rag/reputation/unifiedComment -- neither carries a
# epic) remain plain symmetric overrides like rag/reputation -- neither carries a
# security-hardening or full-file-fetch rationale that would justify a force-on/force-off asymmetry.
# `improvementSignal` is activation wiring only for now -- no tier reads the resolved
# value yet.
# features:
# rag: true
# reputation: false
# unifiedComment: true
# safety: true
# grounding: true
# e2eTests: false
Expand Down
19 changes: 9 additions & 10 deletions packages/loopover-engine/src/focus-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ export type CopycatGateMode = "off" | "warn" | "label" | "block";
// level `false` behaves like any other plain override with no floor/ceiling. This is activation wiring only
// -- no tier reads the resolved value yet (sibling sub-issues #4739-#4746 build the deterministic/LLM/panel
// behavior that will gate on it).
export const CONVERGED_FEATURE_KEYS = ["rag", "reputation", "unifiedComment", "safety", "grounding", "e2eTests", "screenshots", "improvementSignal"] as const;
export const CONVERGED_FEATURE_KEYS = ["rag", "reputation", "safety", "grounding", "e2eTests", "screenshots", "improvementSignal"] as const;
export type ConvergedFeatureKey = (typeof CONVERGED_FEATURE_KEYS)[number];

/** Per-repo activation overrides for the converged review features (`features:` block). `true`/`false` force the
Expand Down Expand Up @@ -542,15 +542,15 @@ export type FocusManifestReviewConfig = {
* otherwise) — this is an ADDITIONAL opt-in on top of `review.inline_comments`, not a replacement gate.
* null/false (default, absent) = no suggestion blocks = byte-identical behavior. (#1956) */
suggestions: boolean | null;
/** `review.changed_files_summary`: when true, the unified review comment (only rendered at all when the
* `unifiedComment` convergence feature is on) gains a deterministic, no-AI "Changed files" collapsible: one
* row per file category (source/test/docs/config/generated), with file counts and +/- totals, via the
* existing `classifyChangedFile` classifier (`src/review/changed-files-classify.ts`, built for this table
* under #2143). null/false (default, absent) = no changed-files section = byte-identical behavior. (#1957) */
/** `review.changed_files_summary`: when true, the unified review comment gains a deterministic, no-AI
* "Changed files" collapsible: one row per file category (source/test/docs/config/generated), with file
* counts and +/- totals, via the existing `classifyChangedFile` classifier
* (`src/review/changed-files-classify.ts`, built for this table under #2143). null/false (default, absent)
* = no changed-files section = byte-identical behavior. (#1957) */
changedFilesSummary: boolean | null;
/** `review.effort_score`: when true, the unified review comment (only rendered when the `unifiedComment`
* convergence feature is on) gains a compact "review effort: N/5 (~M min)" chip — a deterministic, no-AI
* complexity/time estimate from `estimateReviewEffort` (`src/review/review-effort.ts`), weighting each
/** `review.effort_score`: when true, the unified review comment gains a compact "review effort: N/5 (~M min)"
* chip — a deterministic, no-AI complexity/time estimate from `estimateReviewEffort`
* (`src/review/review-effort.ts`), weighting each
* changed file's added lines by its category (source costs most; generated/vendored/lockfiles cost least)
* plus a fixed per-file overhead. Mirrors `changedFilesSummary` exactly: same table, same deterministic
* source, same display-only (never touches the AI prompt) shape. null/false (default, absent) = no chip =
Expand Down Expand Up @@ -1021,7 +1021,6 @@ const EMPTY_FEATURES_CONFIG: FocusManifestFeaturesConfig = {
present: false,
rag: null,
reputation: null,
unifiedComment: null,
safety: null,
grounding: null,
e2eTests: null,
Expand Down
5 changes: 0 additions & 5 deletions src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,6 @@ declare global {
* secret, never a public var. When absent, BYOK is unavailable and review uses the configured instance
* reviewer when available. */
TOKEN_ENCRYPTION_SECRET?: string;
/** #6103: retired -- the unified-comment bridge is now the ONLY PR-comment renderer unconditionally (the
* legacy `buildPublicPrIntelligenceComment` panel this flag used to switch away from was deleted, having
* no remaining production caller). No longer read; kept only so an operator's existing deployment config
* setting it doesn't error. Safe to remove from any env once noticed. */
LOOPOVER_REVIEW_UNIFIED_COMMENT?: string;
/** Inline comments (#inline-comments): when truthy (AND the repo is in LOOPOVER_REVIEW_REPOS AND the repo's
* `.loopover.yml` sets `review.inline_comments: true`), the AI reviewer ALSO leaves quiet, NON-BLOCKING
* inline comments on specific changed lines, layered on top of the decision summary. Default OFF —
Expand Down
4 changes: 2 additions & 2 deletions src/queue/ci-resolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,8 @@ export function refreshLiveMergeState(
// refreshLiveMergeState's #4220 doc comment above prohibits for this act-boundary-adjacent disposition input.
// So this only reuses a memoized value when its key is ALSO in forcedMergeStateKeys/forcedCiAggregateKeys --
// i.e. it was written by a FORCED (genuinely-live-this-pass) call, never by a cached-path reader. On a genuine
// miss (no forced call ran yet this pass, e.g. unifiedCommentAllowed was false) this falls through to a REAL
// live refresh, so behavior can only ever improve (fewer calls) over the pre-fix code, never go staler.
// miss (no forced call has run yet this pass) this falls through to a REAL live refresh, so behavior can only
// ever improve (fewer calls) over the pre-fix code, never go staler.
export function reuseOrRefreshLiveMergeState(
env: Env,
repoFullName: string,
Expand Down
2 changes: 1 addition & 1 deletion src/review/cutover-gate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Convergence (cutover) per-repo gate: an allowlist that activates the PER-PR converged review features one
// repo at a time, so the cutover can be rolled forward (and rolled back) on a single repo without flipping the
// global flags off for everyone. Each per-PR converged feature ALREADY has a global switch (LOOPOVER_REVIEW_SAFETY /
// _GROUNDING / _RAG / _REPUTATION, LOOPOVER_REVIEW_UNIFIED_COMMENT); this adds a SECOND, repo-scoped gate that must
// _GROUNDING / _RAG / _REPUTATION); this adds a SECOND, repo-scoped gate that must
// ALSO pass for the feature to run on a given PR's repo.
//
// Single env var: LOOPOVER_REVIEW_REPOS — a comma-separated allowlist of repo full-names
Expand Down
Loading
Loading