From f12ca4116dcbc67bce811d0db877c2f87c8564fe Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 14 Jul 2026 14:14:51 -0700 Subject: [PATCH 1/2] docs(review): rename gittensory prose to loopover in src/review (batch B) Rebrand cutover cleanup: update brand-name prose in comments across 27 src/review/**/*.ts files (ops, outcomes, parity, PR reconciliation, prompt-injection, public-stats, RAG, repo/skill rendering, secrets scanning, self-tune, stats, and the visual-capture pipeline). Comment-only changes, no behavior change. Deliberate legacy references (the 'gittensory-native' review_audit source discriminator used across parity tracking) are left untouched. --- src/review/ops.ts | 10 +++++----- src/review/outcomes-wire.ts | 6 +++--- src/review/parity-wire.ts | 10 +++++----- src/review/parity.ts | 16 ++++++++-------- src/review/pr-reconciliation.ts | 2 +- src/review/prompt-injection.ts | 2 +- src/review/public-stats.ts | 12 ++++++------ src/review/rag-index.ts | 4 ++-- src/review/rag-wire.ts | 4 ++-- src/review/rag.ts | 6 +++--- src/review/repo-doc-render.ts | 4 ++-- src/review/repo-skill-render.ts | 4 ++-- src/review/reputation-wire.ts | 4 ++-- src/review/review-diff.ts | 2 +- src/review/review-grounding.ts | 4 ++-- src/review/safety.ts | 4 ++-- src/review/secret-patterns.ts | 2 +- src/review/secrets-scan.ts | 2 +- src/review/selftune-wire.ts | 22 +++++++++++----------- src/review/stats.ts | 10 +++++----- src/review/submitter-reputation.ts | 8 ++++---- src/review/unified-comment-bridge.ts | 2 +- src/review/visual/actions-fallback.ts | 8 ++++---- src/review/visual/capture.ts | 14 +++++++------- src/review/visual/paths.ts | 6 +++--- src/review/visual/preview-url.ts | 4 ++-- src/review/visual/shot.ts | 14 +++++++------- 27 files changed, 93 insertions(+), 93 deletions(-) diff --git a/src/review/ops.ts b/src/review/ops.ts index eca57b5536..706e391645 100644 --- a/src/review/ops.ts +++ b/src/review/ops.ts @@ -1,19 +1,19 @@ -// Operational endpoints (the ops capability — reviewbot→gittensory convergence, ADDITIVE, NATIVE port of +// Operational endpoints (the ops capability — reviewbot→loopover convergence, ADDITIVE, NATIVE port of // reviewbot src/core/ops.ts). Bearer-protected per agent. Surfaces enough to answer "is this agent // behaving?": health snapshot (status/verdict breakdown, manual-rate, stuck/failed/DLQ targets, reversals), // confidence-vs-outcome calibration + a recommended floor, and the decision trail for one target. // // SELF-CONTAINED: every type + helper this module needs is defined HERE. No imports from reviewbot. The -// logic is byte-faithful to the reviewbot source; the only deltas are mechanical guards for gittensory's +// logic is byte-faithful to the reviewbot source; the only deltas are mechanical guards for loopover's // stricter tsconfig + an INJECTED-DEPS seam for the runtime-gate-specific pieces. // -// STORAGE: gittensory has no platform/access adapter — `Env` is a global ambient interface with `DB`. +// STORAGE: loopover has no platform/access adapter — `Env` is a global ambient interface with `DB`. // // SCOPE (deferred): reviewbot's ops.ts ALSO exposes the auto-tune override handlers // (handleApplyRecommendation / handleClearOverride / handleOverrideAudit). Those are HEAVILY entangled with // reviewbot's runtime override store (src/core/tunables.ts — a 257-line shadow-soak/sanitize/tighten-only // engine) and are intentionally NOT ported here — porting them would drag the auto-tune engine into the -// gittensory tree. Likewise handleInternalStatus's account-wide AI-error count is the runtime AI-health +// loopover tree. Likewise handleInternalStatus's account-wide AI-error count is the runtime AI-health // pacer (src/core/ai-health.ts) and is taken as an INJECTED dep (default 0). What IS ported is the clean, // D1-only / pure surface: computeAgentHealth, computeCalibration, the bearer gate, and the status / decision // / calibration read endpoints. @@ -126,7 +126,7 @@ export interface OpsAgentConfig { // ── Inlined helpers (byte-faithful from reviewbot src/core/{crypto,util,db}.ts) ────────────────── -/** Storage seam: gittensory's `Env` is a global ambient interface with `DB`. */ +/** Storage seam: loopover's `Env` is a global ambient interface with `DB`. */ function storage(env: Env): D1Database { return env.DB; } diff --git a/src/review/outcomes-wire.ts b/src/review/outcomes-wire.ts index 83f38efb73..13845f4302 100644 --- a/src/review/outcomes-wire.ts +++ b/src/review/outcomes-wire.ts @@ -375,7 +375,7 @@ export async function recordPrOutcome( // ── 2) reversals — a human undid a bot action ──────────────────────────────────────────────────────────────── -/** Was the last GITTENSORY action on this PR a CLOSE? Reads the agent-action audit ledger (audit_events, +/** Was the last LOOPOVER action on this PR a CLOSE? Reads the agent-action audit ledger (audit_events, * eventType `agent.action.`, written by buildAgentActionAudit) — the most-recent SUCCESSFUL action for * this target. A reopen of a bot-CLOSED PR is the high-value "human disagreed with the close" reversal signal. * Fail-safe: a read error → false (record nothing rather than a false reversal). */ @@ -419,7 +419,7 @@ async function wasMergeRecorded(env: Env, targetId: string): Promise { } /** - * Record a REVERSAL — a human overriding a gittensory auto-action — into the eval/audit stores (the + * Record a REVERSAL — a human overriding a loopover auto-action — into the eval/audit stores (the * ground-truth accuracy signal). Mirrors reviewbot recordReversalSignals (runtime.ts ~157/274): * • REOPEN of a bot-CLOSED PR by a CONTRIBUTOR → `reversal_reopened` (the high-value case). Reopens by the * repo OWNER (administrative re-queue) or by a BOT are NOT contributor disputes and are skipped, so the @@ -507,7 +507,7 @@ const BREAKER_EVAL_WINDOW_DAYS = 90; /** * One precision-circuit-breaker tick, run on the scheduled (selftune) cron. Reads the gate-eval confusion - * matrix over gittensory's OWN recorded pr_outcome/gate_decision rows -- SCOPED to `source: 'gittensory-native'` + * matrix over loopover's OWN recorded pr_outcome/gate_decision rows -- SCOPED to `source: 'gittensory-native'` * (#autoclear-deadlock / stale-source): review_audit can also carry historical `gate_decision` rows from the * pre-convergence reviewbot engine (source='reviewbot'), which stopped running once a repo converged and so * never grows. Reading across ALL sources (the pre-fix behavior) let a permanently-frozen legacy prediction set diff --git a/src/review/parity-wire.ts b/src/review/parity-wire.ts index bc5d42a9ab..c6f03903df 100644 --- a/src/review/parity-wire.ts +++ b/src/review/parity-wire.ts @@ -77,13 +77,13 @@ export const LOOPOVER_NATIVE_SOURCE = "gittensory-native"; const PARITY_WINDOW_DAYS = 90; /** - * PURE: map a gittensory gate-check conclusion to the parity-comparable {@link GateAction}, or `null` when the + * PURE: map a loopover gate-check conclusion to the parity-comparable {@link GateAction}, or `null` when the * conclusion carries no comparable terminal decision. * - * The gittensory gate is a CHECK that passes or blocks a merge — it NEVER auto-closes a PR. So the honest, + * The loopover gate is a CHECK that passes or blocks a merge — it NEVER auto-closes a PR. So the honest, * safe mapping is: * • 'success' → 'merge' — the gate would ALLOW the merge. - * • 'failure' | 'action_required' → 'hold' — the gate BLOCKS the merge (holds it for a human); gittensory + * • 'failure' | 'action_required' → 'hold' — the gate BLOCKS the merge (holds it for a human); loopover * does not close, so this is 'hold', not 'close'. This also * keeps the parity SAFETY metric honest: a shadow 'hold' is * never the dangerous "shadow merges where authoritative @@ -189,7 +189,7 @@ export interface ParityReadinessRow extends GateParityRow { } export interface ParityReadinessReport { - /** The authoritative writer (default 'reviewbot') and the shadow writer ('gittensory') being compared. */ + /** The authoritative writer (default 'reviewbot') and the shadow writer ('loopover') being compared. */ authoritative: string; shadow: string; /** Whether enough paired evidence exists anywhere to read parity meaningfully (>= MIN_PARITY_SAMPLE). */ @@ -215,7 +215,7 @@ export async function computeParityReadiness( days: opts.days ?? PARITY_WINDOW_DAYS, nowMs: opts.nowMs ?? Date.now(), // The shadow source MUST match what recordNativeGateDecision stamps ('gittensory-native'); computeGateParity - // defaults `shadow` to 'gittensory', so pass it explicitly or the self-join would find no shadow rows. The + // defaults `shadow` to 'loopover', so pass it explicitly or the self-join would find no shadow rows. The // authoritative side stays the default 'reviewbot' (the deploy-time dual-run writer). shadow: LOOPOVER_NATIVE_SOURCE, ...(opts.project ? { project: opts.project } : {}), diff --git a/src/review/parity.ts b/src/review/parity.ts index bb91e748d9..6931b4af75 100644 --- a/src/review/parity.ts +++ b/src/review/parity.ts @@ -5,16 +5,16 @@ // GROUND TRUTH (the PR's real `pr_outcome` — merged vs closed). The human's normal // merge/close IS the answer key, so accuracy is measurable with zero manual labeling. // computeGateParity — compares TWO systems (an authoritative writer vs a shadow writer) against EACH -// OTHER on the SAME PR at the SAME COMMIT, to prove the gittensory-app gate matches +// OTHER on the SAME PR at the SAME COMMIT, to prove the loopover-app gate matches // reviewbot's before a per-repo cutover. isParityCutoverReady is the hard gate. // -// SELF-CONTAINED NATIVE PORT (reviewbot→gittensory convergence): every type + helper this module needs is +// SELF-CONTAINED NATIVE PORT (reviewbot→loopover convergence): every type + helper this module needs is // defined HERE. No imports from reviewbot — the reviewbot `storage(env)` adapter is inlined as `env.DB`, and -// `Env` is gittensory's global ambient interface (referenced directly). The FOLD logic + SQL are byte-faithful -// to the reviewbot source (src/core/eval.ts); the only deltas are mechanical guards for gittensory's stricter +// `Env` is loopover's global ambient interface (referenced directly). The FOLD logic + SQL are byte-faithful +// to the reviewbot source (src/core/eval.ts); the only deltas are mechanical guards for loopover's stricter // tsconfig (noUncheckedIndexedAccess / exactOptionalPropertyTypes), which don't change behavior. // -// ⚠ LIVE-USE PREREQUISITE (OUT OF SCOPE here): using this live requires gittensory's gate-decision audit rows +// ⚠ LIVE-USE PREREQUISITE (OUT OF SCOPE here): using this live requires loopover's gate-decision audit rows // to carry a `source` (which writer) + `head_sha` (which commit) column — computeGateParity self-joins on // (project, target_id, head_sha) per source, and computeGateEval can scope predictions by source. Those // columns land in a LATER D1 migration. This port is the PURE functions + their tests; the reads degrade @@ -22,7 +22,7 @@ // ── Inlined minimal deps (no reviewbot imports) ───────────────────────────────────────────────────────── -/** The D1 binding this module reads. `Env` is gittensory's global ambient interface (env.DB: D1Database); it is +/** The D1 binding this module reads. `Env` is loopover's global ambient interface (env.DB: D1Database); it is * referenced directly. The reviewbot `storage(env)` adapter maps to `env.DB` here. */ function storage(env: Env): D1Database { return env.DB; @@ -174,13 +174,13 @@ export async function computeGateEval(env: Env, opts: { days: number; nowMs: num } // ── Cross-system gate-decision PARITY (#preconv-parity) ─────────────────────────────────────────────── -// Phase-2 of the gittensory convergence proves the gittensory-app's gate decisions MATCH reviewbot's on +// Phase-2 of the loopover convergence proves the loopover-app's gate decisions MATCH reviewbot's on // the SAME PR at the SAME COMMIT before a per-repo cutover. computeGateEval scores ONE system vs the // realized human outcome (accuracy); this compares TWO systems against EACH OTHER. The two never live in // the same gate_decision row — they're distinct `source` writers in the SAME review_audit store — so we // join the latest gate_decision per (project, target_id, head_sha) for the authoritative source vs a // shadow source. The head_sha is in the join key precisely so reviewbot@shaA is never compared to -// gittensory@shaB (a different commit = a different decision; comparing across commits is meaningless). +// loopover@shaB (a different commit = a different decision; comparing across commits is meaningless). /** The canonical gate actions a decision can take. Anything else (or a missing head_sha) is excluded from * the parity pairing — only a clean merge/close/hold on a known commit is comparable. */ diff --git a/src/review/pr-reconciliation.ts b/src/review/pr-reconciliation.ts index dba36c3353..929f2548f5 100644 --- a/src/review/pr-reconciliation.ts +++ b/src/review/pr-reconciliation.ts @@ -27,7 +27,7 @@ export function isPrReconciliationEnabled(env: { LOOPOVER_PR_RECONCILIATION?: st } /** The same acting-autonomy repo set fanOutAgentRegateSweepJobs sweeps (mirrors sweep-watchdog.ts's own copy of - * this selection) — this reconciliation only makes sense for repos gittensory is actually reviewing. */ + * this selection) — this reconciliation only makes sense for repos loopover is actually reviewing. */ async function watchedRepos(env: Env): Promise> { const repositoriesByKey = new Map((await listRepositories(env)).map((repo) => [repo.fullName.toLowerCase(), repo])); const byKey = new Map(); diff --git a/src/review/prompt-injection.ts b/src/review/prompt-injection.ts index 1d25df7c2a..1d69003359 100644 --- a/src/review/prompt-injection.ts +++ b/src/review/prompt-injection.ts @@ -4,7 +4,7 @@ // we both flag it (a strong negative signal) and redact the literal manipulation so it can't be obeyed // verbatim. // -// SELF-CONTAINED NATIVE PORT (reviewbot→gittensory convergence): every type + pattern this module needs +// SELF-CONTAINED NATIVE PORT (reviewbot→loopover convergence): every type + pattern this module needs // is defined HERE. No imports from reviewbot. The logic is byte-faithful to the reviewbot source // (src/core/prompt-injection.ts); there are no stricter-tsconfig deltas — the module is already total. diff --git a/src/review/public-stats.ts b/src/review/public-stats.ts index 669a77b84d..87e7a92f5a 100644 --- a/src/review/public-stats.ts +++ b/src/review/public-stats.ts @@ -1,10 +1,10 @@ -// Public "proof of power" stats (#1059) — a small, public-safe aggregate of what gittensory's REVIEW SYSTEM has +// Public "proof of power" stats (#1059) — a small, public-safe aggregate of what loopover's REVIEW SYSTEM has // done, powering the above-the-fold homepage counter. Flag-gated by LOOPOVER_PUBLIC_STATS (default OFF): when // off the public endpoint 404s, so the deploy is byte-identical to today until the flag is deliberately set. // // REALTIME: queries the live ledger directly (no rollup/cron) so a new review shows up within the 60s HTTP cache // window. "reviewed" = a distinct PR for which the review system published a public review surface (audit_events -// `github_app.pr_public_surface_published`, scoped to the repos it handles: gittensory, awesome-claude, +// `github_app.pr_public_surface_published`, scoped to the repos it handles: loopover, awesome-claude, // metagraphed); each PR's terminal DISPOSITION is read from the pull_requests cache. (The legacy review_targets // ledger this used to read was orphaned by the convergence cutover — nothing writes it anymore.) // @@ -23,7 +23,7 @@ // PRIVACY: counts only — no PR content, authors, scores, or reward internals. Safe to serve publicly. // // GLOBAL: the homepage total folds in every REGISTERED Orb installation's outcomes (getOrbGlobalStats) on top of -// the own-ledger side, so the counter reflects the whole fleet, not just gittensory's own repos. The own-ledger +// the own-ledger side, so the counter reflects the whole fleet, not just loopover's own repos. The own-ledger // side (audit_events) is a FROZEN snapshot as of the self-host cutover -- it stops growing the day each repo's // live processing moved off this worker, and can never grow again now that the old App has been fully deleted -- // while orb_pr_outcomes keeps growing in realtime for any repo with the central Orb App installed (including @@ -50,7 +50,7 @@ export function isPublicStatsEnabled(env: { return /^(1|true|yes|on)$/i.test(env.LOOPOVER_PUBLIC_STATS ?? ""); } -/** Storage seam: gittensory's `Env` is a global ambient interface with `DB` (mirrors src/review/stats.ts). */ +/** Storage seam: loopover's `Env` is a global ambient interface with `DB` (mirrors src/review/stats.ts). */ function storage(env: Env): D1Database { return env.DB; } @@ -71,7 +71,7 @@ export async function safeAll( } } -/** reviewed = the PRs gittensory actually reviewed (excludes ignored drafts/bots + errors). */ +/** reviewed = the PRs loopover actually reviewed (excludes ignored drafts/bots + errors). */ function reviewedOf(d: { merged: number; closed: number; @@ -105,7 +105,7 @@ function accuracyPct( /** The own-ledger side of public stats is intentionally constrained to an explicit allowlist (privacy: publish * only what's deliberately opted in). Deliberately reads LOOPOVER_PUBLIC_STATS_REPOS, NOT * LOOPOVER_REVIEW_REPOS (the live per-PR-feature cutover allowlist) -- the two once held the same value, but - * diverged once gittensory/awesome-claude/metagraphed moved their LIVE processing to self-host: the cutover + * diverged once loopover/awesome-claude/metagraphed moved their LIVE processing to self-host: the cutover * allowlist correctly went empty, while the historical rows this worker already wrote for them remain real and * safe to publish. Empty allowlist => the own-ledger side reports zero (still fails safe), but does NOT * suppress the separately-gated Orb cross-fleet aggregate (see getPublicStats below). */ diff --git a/src/review/rag-index.ts b/src/review/rag-index.ts index ebc255c7fe..1813d873bf 100644 --- a/src/review/rag-index.ts +++ b/src/review/rag-index.ts @@ -1,6 +1,6 @@ // Convergence (RAG / codebase index — Layer C, flag LOOPOVER_REVIEW_RAG): the INDEX-POPULATION driver. This is // the population half (rag-wire.ts wires RETRIEVAL only): -// it fetches a repo's CODE tree, chunks + embeds it, and upserts vectors+text into the `gittensory-review-rag` +// it fetches a repo's CODE tree, chunks + embeds it, and upserts vectors+text into the `loopover-review-rag` // Vectorize index + the `repo_chunks` table (migration 0051) — so retrieval has a warm index to read from instead // of always seeing a cold namespace and returning "". // @@ -56,7 +56,7 @@ type TreeEntry = { path: string; size?: number | undefined; sha?: string | undef * AHEAD of filePriority's code/doc split. On a repo whose file count exceeds MAX_CHUNKS_PER_REPO, * `indexRepo`'s per-file loop stops once the cap is hit — with only `filePriority` (code=0, doc=1) * as the sort key, a manifest file ties every other source file at priority 0 and then loses on the - * alphabetical tiebreaker, so it can be starved out entirely by volume (verified in prod: gittensory's + * alphabetical tiebreaker, so it can be starved out entirely by volume (verified in prod: loopover's * own package.json never got indexed). These files are already indexable code (JSON/TOML/YAML all * match CODE_EXT_RE in `./rag`) — this only reorders them, it does not change what's included. * Reuses the same "manifest-like filename" classifiers signals/path-matchers.ts already exports for diff --git a/src/review/rag-wire.ts b/src/review/rag-wire.ts index 88c85e50a1..831ac8aacd 100644 --- a/src/review/rag-wire.ts +++ b/src/review/rag-wire.ts @@ -38,11 +38,11 @@ const MAX_QUERY_DIFF_CHARS = 4000; const RAG_TOP_K = 12; /** Relevance floor for the cosine matches — drops low-relevance "neighbours" that are noise, not real context * (bge-m3 scores relevant code ~0.5-0.7 and clear noise <0.35; 0.4 is a conservative floor). Matches reviewbot's - * core config (`rag: { minScore: 0.4 }`); gittensory previously used 0 (off), which kept that noise as + * core config (`rag: { minScore: 0.4 }`); loopover previously used 0 (off), which kept that noise as * "relevant code" and itself drove false positives. (#GAP-2) */ const RAG_MIN_SCORE = 0.4; /** Rerank the cosine top-K by exact-term overlap before injecting, to demote vector-accident matches (high - * cosine, no real term overlap). Matches reviewbot's core config (`rag: { reranker: "bm25" }`); gittensory + * cosine, no real term overlap). Matches reviewbot's core config (`rag: { reranker: "bm25" }`); loopover * previously left this off. (#283 / #GAP-2) */ const RAG_RERANKER = "bm25" as const; diff --git a/src/review/rag.ts b/src/review/rag.ts index 224fcead74..4ed0f176cd 100644 --- a/src/review/rag.ts +++ b/src/review/rag.ts @@ -6,9 +6,9 @@ // code), bge-m3 embeds ~1 vector per file, and a hard MAX_CHUNKS_PER_REPO cap bounds stored // vectors. Queries are ~1 vector/review. // -// SELF-CONTAINED NATIVE PORT (reviewbot→gittensory convergence): every type + helper this module needs is +// SELF-CONTAINED NATIVE PORT (reviewbot→loopover convergence): every type + helper this module needs is // defined HERE. No imports from reviewbot. The logic is byte-faithful to the reviewbot source -// (src/core/rag.ts); the only deltas are (1) mechanical guards for gittensory's stricter tsconfig +// (src/core/rag.ts); the only deltas are (1) mechanical guards for loopover's stricter tsconfig // (noUncheckedIndexedAccess + exactOptionalPropertyTypes), which do not change behavior, and (2) the infra // it needs — the vector index, the AI embedding model, and the chunk-text store — is INJECTED via the // VectorAdapter / InferenceAdapter / StorageAdapter interfaces (passed as params) instead of reviewbot's @@ -102,7 +102,7 @@ const CHUNK_CHARS = 16000; // per-file chunk budget; only files larger than this const CHUNK_OVERLAP = 1500; /** Hard per-repo stored-vector cap — bounds a repo-controlled, unboundedly-growable store. Source is * prioritized so it survives the cap. Raised from 1500 (2026-07-09): all 3 currently-gated repos were - * sitting AT the old cap (confirmed live), and gittensory's own indexable tree alone is within range of + * sitting AT the old cap (confirmed live), and loopover's own indexable tree alone is within range of * it before accounting for large files splitting into multiple chunks -- meaning real code was silently * never indexed. Storage/search cost at this scale is trivial for Qdrant regardless of cap size (the * bound exists to protect against a pathological future repo, not because 4000 vectors is expensive); diff --git a/src/review/repo-doc-render.ts b/src/review/repo-doc-render.ts index 6e4533d756..c73a1f91a4 100644 --- a/src/review/repo-doc-render.ts +++ b/src/review/repo-doc-render.ts @@ -14,8 +14,8 @@ import type { GeneratedDocMarkers } from "./generated-doc-refresh"; /** HTML-comment marker pair bracketing the machine-generated section of every AGENTS.md this engine writes. * Content outside this pair (added by a maintainer before the start marker or after the end marker) is treated * as permanently manual and is never touched by a refresh (#3004) -- see generated-doc-refresh.ts. */ -export const REPO_DOC_MARKER_START = ""; -export const REPO_DOC_MARKER_END = ""; +export const REPO_DOC_MARKER_START = ""; +export const REPO_DOC_MARKER_END = ""; export const REPO_DOC_MARKERS: GeneratedDocMarkers = { start: REPO_DOC_MARKER_START, end: REPO_DOC_MARKER_END }; const MAX_RENDERED_TOP_LEVEL_DIRECTORIES = 12; diff --git a/src/review/repo-skill-render.ts b/src/review/repo-skill-render.ts index 6cc14612e1..d039ce3fd9 100644 --- a/src/review/repo-skill-render.ts +++ b/src/review/repo-skill-render.ts @@ -13,8 +13,8 @@ import type { RepoProfile, RepoProfileContributionWorkflow } from "./repo-profile"; import type { GeneratedDocMarkers } from "./generated-doc-refresh"; -export const REPO_SKILL_MARKER_START = ""; -export const REPO_SKILL_MARKER_END = ""; +export const REPO_SKILL_MARKER_START = ""; +export const REPO_SKILL_MARKER_END = ""; export const REPO_SKILL_MARKERS: GeneratedDocMarkers = { start: REPO_SKILL_MARKER_START, end: REPO_SKILL_MARKER_END }; function hasBlockingGate(contributionWorkflow: RepoProfileContributionWorkflow): boolean { diff --git a/src/review/reputation-wire.ts b/src/review/reputation-wire.ts index 01c56f0052..49acf44f3c 100644 --- a/src/review/reputation-wire.ts +++ b/src/review/reputation-wire.ts @@ -1,5 +1,5 @@ // Convergence (reputation) wiring: feeds the ported, INTERNAL-only submitter-reputation signal -// (`./submitter-reputation`) into gittensory's review path as an anti-abuse extension of the existing +// (`./submitter-reputation`) into loopover's review path as an anti-abuse extension of the existing // AI-spend gate. A new / burst / low-reputation submitter is downgraded to a DETERMINISTIC-ONLY review // (the AI neurons are skipped); a good-reputation submitter proceeds normally. After the gate decides, the // terminal outcome is recorded so the signal stays current. @@ -96,7 +96,7 @@ export async function getEffectiveSubmitterReputation( * see {@link getEffectiveSubmitterReputation}) and report whether the AI-spend gate should downgrade to a * deterministic-only review. When the flag is OFF this returns false IMMEDIATELY — no DB read — so the * AI-spend gate is byte-identical to today. `project` namespaces the per-(project, submitter) rows - * (gittensory uses the repo full name). NEVER throws: the ported module already degrades to neutral on error. + * (loopover uses the repo full name). NEVER throws: the ported module already degrades to neutral on error. * * Also checks submission CADENCE (#4514): every quality-based signal above only tells you whether a * submitter's outcomes were good or bad, never how FAST they arrived -- a fast, well-formed, strategically diff --git a/src/review/review-diff.ts b/src/review/review-diff.ts index 1c20e22dc5..ffcd791acc 100644 --- a/src/review/review-diff.ts +++ b/src/review/review-diff.ts @@ -1,5 +1,5 @@ // Bounded, source-first, hunk-aware unified-diff builder for the AI reviewers. -// Ported from reviewbot (the source-of-truth engine, src/core/diff.ts). The previous gittensory builder +// Ported from reviewbot (the source-of-truth engine, src/core/diff.ts). The previous loopover builder // was a blind head-slice that `break`-DROPPED whole files on overflow with no priority ordering — so on a // multi-file PR the file that DEFINES a symbol could be dropped while another file references it, and the // model then hallucinated "missing import / undefined symbol" (the metagraphed #1528 false-positive class, diff --git a/src/review/review-grounding.ts b/src/review/review-grounding.ts index 1436215d6c..1f6feb36ee 100644 --- a/src/review/review-grounding.ts +++ b/src/review/review-grounding.ts @@ -7,9 +7,9 @@ // features.fullFileContext (default OFF — wire once here, flip on per chain from its config). Fully // fail-safe: any fetch error degrades to "no grounding" and the review proceeds on the diff alone. // -// SELF-CONTAINED NATIVE PORT (reviewbot→gittensory convergence): every type + helper this module needs is +// SELF-CONTAINED NATIVE PORT (reviewbot→loopover convergence): every type + helper this module needs is // defined HERE. No imports from reviewbot. The logic is byte-faithful to the reviewbot source -// (src/core/review-grounding.ts); the only deltas are (1) mechanical guards for gittensory's stricter +// (src/core/review-grounding.ts); the only deltas are (1) mechanical guards for loopover's stricter // tsconfig (noUncheckedIndexedAccess + exactOptionalPropertyTypes), which do not change behavior, and // (2) the one I/O dependency (GitHub file fetch) is INJECTED via the FileFetcher interface + explicit // params instead of reviewbot's RunContext/ReviewTarget/github helpers, so fetchFullFileContents is diff --git a/src/review/safety.ts b/src/review/safety.ts index 8310ee0f53..aa75e3e90b 100644 --- a/src/review/safety.ts +++ b/src/review/safety.ts @@ -1,5 +1,5 @@ // Convergence (safety) feature flag + helpers that wire the ported safety modules -// (`./prompt-injection` + `./secrets-scan`) into gittensory's review path. +// (`./prompt-injection` + `./secrets-scan`) into loopover's review path. // // Single env switch: LOOPOVER_REVIEW_SAFETY. Default OFF (unset/"false") — when OFF none of the helpers here // alter inputs or findings, so the review path is byte-identical to today. Truthy follows the codebase @@ -92,7 +92,7 @@ function locationSummaryFor(hits: SecretScanLocationMatch[]): string { /** * Scan the PR diff for leaked secrets and, on a hit, return ONE `AdvisoryFinding` (else null). Mapped to - * gittensory's {@link AdvisoryFinding} shape. + * loopover's {@link AdvisoryFinding} shape. * * Only CONCRETE credential formats ({@link HARD_SECRET_KINDS}) produce the critical `secret_leak` code that * `rules/advisory.ts`'s `isConfiguredGateBlocker` treats as an unconditional hard blocker — the weak diff --git a/src/review/secret-patterns.ts b/src/review/secret-patterns.ts index 6024bc96d9..978e71b0a7 100644 --- a/src/review/secret-patterns.ts +++ b/src/review/secret-patterns.ts @@ -33,7 +33,7 @@ export const SECRET_PATTERNS: SecretPattern[] = [ re: /\bAKIA[0-9A-Z]{16}\b/, // AWS's own officially published documentation placeholder (used across the AWS SDK's own docs and // countless tutorials specifically so it reads as inert) -- confirmed to have caused 4 false-positive PR - // closes in gittensory's own #4284 subprocess-env-redaction-helper epic (a PR building a REDACTION + // closes in loopover's own #4284 subprocess-env-redaction-helper epic (a PR building a REDACTION // feature needed this exact literal as a realistic-looking non-secret test fixture). Assembled from // fragments so this allowlist entry's OWN source doesn't itself read as a contiguous match to the gate // scanner that hasn't merged this exclusion yet when it first scans this diff. diff --git a/src/review/secrets-scan.ts b/src/review/secrets-scan.ts index 11d879e0bd..ddd9c3943a 100644 --- a/src/review/secrets-scan.ts +++ b/src/review/secrets-scan.ts @@ -1,7 +1,7 @@ // Reusable secret-pattern scanner (the `secretsScan` capability). Deterministic, no deps. // Callers run scanForSecrets() on submitted diff/text; a hit typically forces a close/manual verdict. // -// SELF-CONTAINED NATIVE PORT (reviewbot→gittensory convergence): byte-faithful to the reviewbot source +// SELF-CONTAINED NATIVE PORT (reviewbot→loopover convergence): byte-faithful to the reviewbot source // (src/core/secrets-scan.ts); there are no stricter-tsconfig deltas — the module is already total. No // imports from reviewbot. // diff --git a/src/review/selftune-wire.ts b/src/review/selftune-wire.ts index 8eb488101f..68c3677e08 100644 --- a/src/review/selftune-wire.ts +++ b/src/review/selftune-wire.ts @@ -1,10 +1,10 @@ // Convergence (#self-improve) — wires the ported self-improvement loop (src/review/auto-tune.ts + -// src/review/auto-apply.ts) into gittensory's cron behind the default-OFF `LOOPOVER_REVIEW_SELFTUNE` flag. +// src/review/auto-apply.ts) into loopover's cron behind the default-OFF `LOOPOVER_REVIEW_SELFTUNE` flag. // // SAFETY CONTRACT (must hold under every path): // • flag-OFF (default) → the cron enqueues NO selftune job and this module is never reached; ZERO tuning // work, NO override read/written, the worker is byte-identical to today. -// • flag-ON → the loop can ONLY EVER TIGHTEN the gate. It computes tuning recommendations from gittensory's +// • flag-ON → the loop can ONLY EVER TIGHTEN the gate. It computes tuning recommendations from loopover's // OWN outcome data, SHADOW-SOAKS only STRICTLY-TIGHTENING recommendations, and AUTO-PROMOTES a soaked // shadow override to live ONLY after the soak window passes the gate (tightening + evidence + soaked). // Every action is recorded to override_audit. A loosening change is NEVER applied — the ported @@ -12,13 +12,13 @@ // loosening directive into the apply path (closeFalse is held at 0, so the one loosening branch of // `computeTuningRecommendations` is unreachable and carries no payload anyway). // -// EVAL INPUT — ADAPTED TO GITTENSORY'S OWN OUTCOME DATA (NOT reviewbot's review_audit, which does not exist in -// gittensory's migrations — parity.computeGateEval would read an empty table here). The ported auto-tune -// advisor consumes a GateEvalReport (per-project confusion matrix). We build that report from gittensory's +// EVAL INPUT — ADAPTED TO LOOPOVER'S OWN OUTCOME DATA (NOT reviewbot's review_audit, which does not exist in +// loopover's migrations — parity.computeGateEval would read an empty table here). The ported auto-tune +// advisor consumes a GateEvalReport (per-project confusion matrix). We build that report from loopover's // NATIVE outcome sources via the SAME aggregation services ops-wire already reuses (no new queries / schema): // • agent_recommendation_outcomes (#543) — the positive/negative resolved split (buildRepoOutcomeCalibration). // Only maintainer-lane outcomes are authoritative enough for live self-tune policy changes; contributor-lane -// closures can be self-authored and stay reporting-only. A maintainer-lane NEGATIVE outcome (gittensory +// closures can be self-authored and stay reporting-only. A maintainer-lane NEGATIVE outcome (loopover // recommended "proceed", the human CLOSED) is the gittensory-native analogue of reviewbot's "would-merge // BUT human closed" (mergeFalse) — the dangerous error a TIGHTENING fixes. // The mapping is deliberately conservative: it only ever populates the would-MERGE side of the matrix, so the @@ -27,7 +27,7 @@ // CONFIG-APPLICATION — WIRED (live read-back, tightening-only): // The ported override model is `confidenceFloor` (a proceed-confidence floor in [0,1]) + `scopeCap`. The live // read-back lives in resolveRepositorySettings → `applySelfTuneOverrideToSettings`, gated by the SAME default-OFF -// LOOPOVER_REVIEW_SELFTUNE flag: it translates a promoted `confidenceFloor` into gittensory's NATIVE readiness +// LOOPOVER_REVIEW_SELFTUNE flag: it translates a promoted `confidenceFloor` into loopover's NATIVE readiness // tunable by RAISING an EXISTING `qualityGateMinScore` to `round(confidenceFloor * 100)` via a `max()`. By // construction this can ONLY tighten — it never CREATES a readiness gate the operator didn't set, and never // LOWERS one — so the always-tightening recommendation (this module only ever populates the would-merge error @@ -59,8 +59,8 @@ export function isSelfTuneEnabled(env: { export const SELFTUNE_BASE_CONFIDENCE_FLOOR = 0; /** - * PURE: build the ported GateEvalReport from gittensory's NATIVE recommendation-outcome calibration. The - * recommendation NEGATIVE outcomes (gittensory said proceed, the human CLOSED) map to the would-merge ERROR + * PURE: build the ported GateEvalReport from loopover's NATIVE recommendation-outcome calibration. The + * recommendation NEGATIVE outcomes (loopover said proceed, the human CLOSED) map to the would-merge ERROR * (`mergeFalse`); POSITIVE outcomes map to `mergeConfirmed`. ONLY the would-merge side is populated, so the * advisor can ONLY produce a TIGHTENING (raise the floor) or no recommendation — never a loosening (the * close-side counters stay 0, so `computeTuningRecommendations`' one loosening branch is unreachable). @@ -93,7 +93,7 @@ export function evalRowFromCalibration(project: string, positive: number, negati }; } -/** Build the per-project GateEvalReport from gittensory's recommendation-outcome calibration for one repo. */ +/** Build the per-project GateEvalReport from loopover's recommendation-outcome calibration for one repo. */ async function buildEvalRow(env: Env, repoFullName: string): Promise { const calibration = await buildRepoOutcomeCalibration(env, repoFullName, undefined, { maintainerOnly: true }); return evalRowFromCalibration(repoFullName, calibration.recommendations.positive, calibration.recommendations.negative); @@ -138,7 +138,7 @@ async function selfTuneRepos(env: Env): Promise { /** * One self-improvement tick, run on the cron. FAILS SAFE: a per-repo error is logged and the pass continues; a * top-level error is swallowed (tuning must never break the cron). For each agent-configured repo it: (1) builds - * the GateEvalReport from gittensory's own outcome data; (2) computes tuning recommendations; (3) SHADOW-SOAKS + * the GateEvalReport from loopover's own outcome data; (2) computes tuning recommendations; (3) SHADOW-SOAKS * any strictly-tightening recommendation; (4) PROMOTES a soaked shadow override to live ONLY when the gate * passes (tightening + evidence + soaked) — all via the ported runAutoApplyRecommendations, which records every * action to override_audit and NEVER applies a loosening change. diff --git a/src/review/stats.ts b/src/review/stats.ts index 02446158f0..741520fddb 100644 --- a/src/review/stats.ts +++ b/src/review/stats.ts @@ -1,4 +1,4 @@ -// Cross-project stats endpoint (reviewbot→gittensory convergence — ADDITIVE, NATIVE port of reviewbot +// Cross-project stats endpoint (reviewbot→loopover convergence — ADDITIVE, NATIVE port of reviewbot // src/core/stats.ts). Read-only feed powering a local dashboard: per-project, per-verdict decision counts // bucketed over time, plus human-reversal counts + non-content gate-decision counts — all from D1 (the // source of truth; full history, no Analytics sampling cap). Returns ONLY aggregate counts, never PR @@ -6,10 +6,10 @@ // token (the token is the gate, not the origin). // // SELF-CONTAINED: every type + helper this module needs is defined HERE. No imports from reviewbot. The -// logic is byte-faithful to the reviewbot source; the only deltas are mechanical guards for gittensory's +// logic is byte-faithful to the reviewbot source; the only deltas are mechanical guards for loopover's // stricter tsconfig + an INJECTED-DEPS seam. // -// STORAGE: gittensory has no platform/access adapter — `Env` is a global ambient interface with `DB`. +// STORAGE: loopover has no platform/access adapter — `Env` is a global ambient interface with `DB`. // // EVAL / PARITY / TUNING are the runtime gate's eval engine (reviewbot src/core/{eval,tuning}.ts) — they // are NOT part of this aggregation and are heavily entangled with the gate. They are taken as INJECTED @@ -120,7 +120,7 @@ export const defaultStatsEvalDeps: StatsEvalDeps = { // ── Inlined helpers (byte-faithful from reviewbot src/core/{crypto,util}.ts) ───────────────────── -/** Storage seam: gittensory's `Env` is a global ambient interface with `DB`. */ +/** Storage seam: loopover's `Env` is a global ambient interface with `DB`. */ function storage(env: Env): D1Database { return env.DB; } @@ -481,7 +481,7 @@ export async function computeStats( }; } -/** GET //internal/parity?days=90&shadow=gittensory — bearer-gated, CORS-open cross-system gate +/** GET //internal/parity?days=90&shadow=loopover — bearer-gated, CORS-open cross-system gate * parity feed (the per-repo cutover gate). Scoped to the agent's own project. Mirrors handleStats. */ export async function handleParity( request: Request, diff --git a/src/review/submitter-reputation.ts b/src/review/submitter-reputation.ts index 9744297ace..f773be09a4 100644 --- a/src/review/submitter-reputation.ts +++ b/src/review/submitter-reputation.ts @@ -15,19 +15,19 @@ // out of the window and trapped contributors auto-correct with no migration. recordSubmissionOutcome still // maintains submitter_stats for /stats, but the SIGNAL is now derived from review_targets. // -// SELF-CONTAINED NATIVE PORT (reviewbot→gittensory convergence): every type + helper this module needs is +// SELF-CONTAINED NATIVE PORT (reviewbot→loopover convergence): every type + helper this module needs is // defined HERE. No imports from reviewbot — the reviewbot `storage(env)` adapter is inlined as `env.DB`, and // the `Env` / `ReputationConfig` types are declared locally. The CLASSIFY/SIGNAL/COUNT logic is byte-faithful // to the reviewbot source (src/core/submitter-reputation.ts); the only deltas are mechanical guards for -// gittensory's stricter tsconfig (noUncheckedIndexedAccess / exactOptionalPropertyTypes), which don't change +// loopover's stricter tsconfig (noUncheckedIndexedAccess / exactOptionalPropertyTypes), which don't change // behavior. ADDITIVE + DORMANT: the DB-touching reads/writes assume the reviewbot D1 tables (review_targets, -// submitter_stats) — gittensory does not yet have them, so getSubmitterReputation / recordSubmissionOutcome +// submitter_stats) — loopover does not yet have them, so getSubmitterReputation / recordSubmissionOutcome // degrade fail-safe (neutral / no-op) until a later migration lands them. The PURE classifiers // (classifyOutcome / countOutcomes / signalFromCounts) are usable immediately. // ── Inlined minimal deps (no reviewbot imports) ───────────────────────────────────────────────────────── -/** The D1 binding this module reads/writes. `Env` is gittensory's global ambient interface (env.DB: D1Database); +/** The D1 binding this module reads/writes. `Env` is loopover's global ambient interface (env.DB: D1Database); * it is referenced directly. The reviewbot `storage(env)` adapter maps to `env.DB` here. */ function storage(env: Env): D1Database { return env.DB; diff --git a/src/review/unified-comment-bridge.ts b/src/review/unified-comment-bridge.ts index 0a45cf8751..f9745c61bc 100644 --- a/src/review/unified-comment-bridge.ts +++ b/src/review/unified-comment-bridge.ts @@ -171,7 +171,7 @@ function gateVerdictReason(gate: GateCheckEvaluation): string | undefined { // joined string (title + action per finding) -- and buildDualReviewNotes folds those SAME `gate.blockers` // into the reviewer notes that render as the "Why this is blocked" section a few lines below. Falling back // to `gate.summary`/`gate.title` here would print the identical blocker text TWICE in one comment (the - // real-world bug behind gittensory PR #5347's screenshot). Only reachable when gate.blockers is non-empty, + // real-world bug behind loopover PR #5347's screenshot). Only reachable when gate.blockers is non-empty, // since evaluateGateCheckCore only sets `blockers: []` on a neutral/success conclusion -- so this never // affects the held/neutral case above, which has no "Why this is blocked" section to duplicate against. if (gate.blockers.length > 0) return undefined; diff --git a/src/review/visual/actions-fallback.ts b/src/review/visual/actions-fallback.ts index 8b2bf4ca77..2640a1e8e0 100644 --- a/src/review/visual/actions-fallback.ts +++ b/src/review/visual/actions-fallback.ts @@ -4,7 +4,7 @@ // preview-url.ts's discovery chain (Deployments API -> commit-check scan -> bot PR-comment scan) only ever // finds a preview that SOME OTHER CI already produced. This module is the trusted half of a fork-safe, // two-sided pipeline whose untrusted half is .github/workflows/visual-capture-fallback.yml: -// 1. gittensory DISPATCHES that workflow (`workflow_dispatch`, always resolved against the repo's default +// 1. loopover DISPATCHES that workflow (`workflow_dispatch`, always resolved against the repo's default // branch) with the PR number + head SHA as inputs. A `workflow_dispatch` call always runs the DISPATCHED // ref's copy of the workflow file, so a contributor can never smuggle a modified workflow definition // through their own PR branch -- unlike a `pull_request`-triggered workflow, which runs the version @@ -15,7 +15,7 @@ // GitHub Actions artifact. It never holds a credential of any kind, and it never needs one: the untrusted // code's network reach never leaves the runner's own localhost, so GitHub's stock per-job isolation is // already the full sandbox this needs -- no bespoke Firecracker/gVisor sandbox to build or maintain. -// 3. On completion, GitHub delivers a `workflow_run` webhook. The caller (queue processor) uses gittensory's +// 3. On completion, GitHub delivers a `workflow_run` webhook. The caller (queue processor) uses loopover's // OWN, already-trusted installation token -- NEVER a token that passed through step 2's untrusted job -- // to list and download that run's artifact via `fetchFallbackArtifactShots` below. // @@ -24,7 +24,7 @@ // every other fetch in this codebase, which only ever talks to api.github.com or a *.workers.dev/*.pages.dev // preview host. isGithubArtifactStorageUrl is the SSRF allowlist extension this genuinely new source needs: // isSafeHttpUrl's general public-https safety, PLUS a closed host-suffix allowlist (mirrors preview-url.ts's -// own PREVIEW_HOST_SUFFIXES pattern), so a malformed or unexpected API response can never make gittensory's +// own PREVIEW_HOST_SUFFIXES pattern), so a malformed or unexpected API response can never make loopover's // backend fetch an attacker-influenced or internal address. // // A `workflow_dispatch` run carries no natural PR association (unlike a `pull_request`-triggered run), so the @@ -76,7 +76,7 @@ export function isGithubArtifactStorageUrl(raw: string): boolean { } // --------------------------------------------------------------------------------------------------------- -// Dispatch: gittensory -> GitHub (workflow_dispatch), pinned to the default branch. +// Dispatch: loopover -> GitHub (workflow_dispatch), pinned to the default branch. // --------------------------------------------------------------------------------------------------------- /** Dispatch the fallback capture workflow for one PR. `ref` MUST be the repo's default branch (never the PR's diff --git a/src/review/visual/capture.ts b/src/review/visual/capture.ts index c54fe71732..db1fe4d0f5 100644 --- a/src/review/visual/capture.ts +++ b/src/review/visual/capture.ts @@ -1,4 +1,4 @@ -// Realtime visual capture (reviewbot→gittensory convergence — visual port). taopedia-style before/after. +// Realtime visual capture (reviewbot→loopover convergence — visual port). taopedia-style before/after. // // before = production (review.visual.production_url, falling back to the global PUBLIC_SITE_ORIGIN env var); // after = the PR's preview-deploy URL, discovered the @@ -10,9 +10,9 @@ // bucket's own public URL — see resolveShotUrl below. Either way, GitHub's image proxy fetches a fast // static object instead of waiting on a live browser render. // -// PORTED from reviewbot's src/agents/gittensory/capture.ts (mapFilesToRoutes / routeForFile / capturePage / -// buildCapture), adapted to gittensory bindings + origins. The agent-config-driven route rules, authed-route -// preview session, and explicit-route override are intentionally dropped here — gittensory's UI uses the +// PORTED from reviewbot's src/agents/loopover/capture.ts (mapFilesToRoutes / routeForFile / capturePage / +// buildCapture), adapted to loopover bindings + origins. The agent-config-driven route rules, authed-route +// preview session, and explicit-route override are intentionally dropped here — loopover's UI uses the // default TanStack route convention; those hooks can return if a per-repo visual config is added. import { base64Encode, sha256Hex } from "../../utils/crypto"; import type { AiContentBlock } from "../../types"; @@ -33,7 +33,7 @@ import { encodeScrollGif, isScrollGifAvailable } from "./scroll-gif"; const NAMESPACE = "loopover"; const DEFAULT_ROUTES = ["/"]; -// The app-folder segment is a wildcard, not hardcoded to gittensory-ui: metagraphed's UI (apps/ui/src/routes/) +// The app-folder segment is a wildcard, not hardcoded to loopover-ui: metagraphed's UI (apps/ui/src/routes/) // uses the identical TanStack flat-file convention `routeForFile` below implements, just under a different app // folder name. Only ever matched against the CURRENT repo's own changed-file paths (see mapFilesToRoutes' // caller), so widening this carries no cross-repo ambiguity risk. @@ -202,7 +202,7 @@ export async function fetchExternalScreenshotContentBlock(url: string): Promise< } } -/** Inputs the capture pipeline needs about the PR under review (resolved by the caller from gittensory data). */ +/** Inputs the capture pipeline needs about the PR under review (resolved by the caller from loopover data). */ export interface CaptureTarget { repoFullName: string; prNumber: number; @@ -268,7 +268,7 @@ export type VisualRoutesInput = { paths?: readonly string[] | null | undefined; /** * Resolve which routes to screenshot for this PR: an explicit, always-screenshotted `paths` list from * `review.visual.routes` REPLACES automatic file-to-route inference entirely when non-empty (simpler and - * more robust for a repo whose routing convention isn't gittensory-ui's TanStack file-based one); absent/ + * more robust for a repo whose routing convention isn't loopover-ui's TanStack file-based one); absent/ * empty config falls through to `mapFilesToRoutes` unchanged, so this is byte-identical to today by default. * `maxRoutes` applies to either path — an explicit list is capped too, not just inferred routes. */ diff --git a/src/review/visual/paths.ts b/src/review/visual/paths.ts index 9d8a13f187..18e81de29b 100644 --- a/src/review/visual/paths.ts +++ b/src/review/visual/paths.ts @@ -1,8 +1,8 @@ -// Visual-path classifier (reviewbot→gittensory convergence — visual capture port). +// Visual-path classifier (reviewbot→loopover convergence — visual capture port). // -// PORTED VERBATIM from reviewbot's src/agents/gittensory/capabilities.ts `isVisualPath` (the three +// PORTED VERBATIM from reviewbot's src/agents/loopover/capabilities.ts `isVisualPath` (the three // VISUAL_PATTERNS), with the first pattern's app-folder segment widened to a wildcard (#3611 follow-up) so it -// isn't gittensory-ui-only — see capture.ts's DEFAULT_ROUTE_FILE for the same generalization. This is the +// isn't loopover-ui-only — see capture.ts's DEFAULT_ROUTE_FILE for the same generalization. This is the // EMPHATIC gate: screenshots fire ONLY for WEB-VISIBLE changes — any frontend app folder (apps/*/**, e.g. // apps/loopover-ui/** or apps/ui/**), a public asset (public/**, e.g. an OG image), or a front-of-house // source extension (.tsx/.jsx/.css/.scss/.sass/.less/.html/.svg/.astro/.vue/.svelte/.mdx). A backend change diff --git a/src/review/visual/preview-url.ts b/src/review/visual/preview-url.ts index 4b11136f3f..d3b9c85a4b 100644 --- a/src/review/visual/preview-url.ts +++ b/src/review/visual/preview-url.ts @@ -1,4 +1,4 @@ -// Preview-URL discovery (reviewbot→gittensory convergence — visual capture port). +// Preview-URL discovery (reviewbot→loopover convergence — visual capture port). // // PORTED from reviewbot's src/core/github.ts (getLatestDeploymentStatus, extractPreviewUrl, // findPreviewUrlFromChecks, findPreviewUrlFromPrComments, getPreviewBuildState) + the @@ -10,7 +10,7 @@ // 3. the Cloudflare Workers Builds bot's PR comment (where 2026-era Cloudflare publishes the link). // getPreviewBuildState distinguishes "still building" (keep polling) from "failed" / "no build". // -// gittensory has no fetch-based GitHub JSON helper of its own (its src/github layer uses Octokit), so +// loopover has no fetch-based GitHub JSON helper of its own (its src/github layer uses Octokit), so // this module carries a small fetch helper mirroring reviewbot's. Callers pass an installation token // (resolved via createInstallationToken). Every helper degrades to null/absent on failure — preview // discovery must NEVER sink a review. diff --git a/src/review/visual/shot.ts b/src/review/visual/shot.ts index e9e380bdcc..81ab9db160 100644 --- a/src/review/visual/shot.ts +++ b/src/review/visual/shot.ts @@ -1,11 +1,11 @@ -// Screenshot endpoint for the realtime before/after capture (reviewbot→gittensory convergence — visual port). +// Screenshot endpoint for the realtime before/after capture (reviewbot→loopover convergence — visual port). // -// PORTED from reviewbot's src/agents/gittensory/shot.ts. CHANGES for gittensory: +// PORTED from reviewbot's src/agents/loopover/shot.ts. CHANGES for loopover: // • puppeteer import unchanged (@cloudflare/puppeteer), SSRF guard now isSafeHttpUrl from ../content-lane/safe-url -// • bindings: env.BROWSER (Browser Rendering) + env.REVIEW_AUDIT (R2) — gittensory's R2 binding is +// • bindings: env.BROWSER (Browser Rendering) + env.REVIEW_AUDIT (R2) — loopover's R2 binding is // REVIEW_AUDIT, NOT reviewbot's env.AUDIT. // • r2 key prefix default 'loopover/shots/'; on-demand render allowlist's production host = PUBLIC_SITE_ORIGIN. -// • no reviewbot REVIEWBOT_* secrets / REST fallback — gittensory renders via the BROWSER binding only. +// • no reviewbot REVIEWBOT_* secrets / REST fallback — loopover renders via the BROWSER binding only. // // Two modes: // GET /loopover/shot?key= -> stream a pre-rendered PNG from R2 (fast; GitHub's image proxy @@ -30,9 +30,9 @@ export interface CaptureShotOptions { * VERIFIED (#4109): `emulateMediaFeatures` maps to CDP's `Emulation.setEmulatedMedia`, which only changes * what CSS media queries and `window.matchMedia` report — it cannot write `localStorage` and has NO effect * on any theme mechanism that reads an explicit stored preference instead of consulting - * `prefers-color-scheme`. This is reproducible today against gittensory's own UI: `apps/loopover-ui` + * `prefers-color-scheme`. This is reproducible today against loopover's own UI: `apps/loopover-ui` * forces dark mode unconditionally in its no-flash script (`components/site/theme-toggle.tsx`), never - * consulting the media feature at all, so a `light` vs `dark` capture of gittensory's own site renders + * consulting the media feature at all, so a `light` vs `dark` capture of loopover's own site renders * byte-identical regardless of this option. `themeStorageKey` below is the fallback for exactly that class * of app. */ theme?: ShotTheme; @@ -59,7 +59,7 @@ type ScreenshotPage = { // free to run. This pipeline's cost is Browser Rendering wall-clock: every route already renders up to 4 PNGs // (before+after × desktop+mobile), multiplied again by `review.visual.themes` when configured -- a 3rd // viewport would raise that to 6 (a 50% jump) for every repo, every review, forever, not just the reviewer -// who wants tablet coverage. gittensory's own pair already straddles a real breakpoint on each side (1440 is +// who wants tablet coverage. loopover's own pair already straddles a real breakpoint on each side (1440 is // past a typical Tailwind `lg`; 390 is an iPhone-class portrait well under `sm`), so it is not an arbitrary // choice either. If a repo genuinely needs tablet coverage, that is a `review.visual` opt-in follow-up // (mirroring `routes.maxRoutes`'s per-repo override precedent) -- not a default-on cost increase for repos From c1c682abfac68c383ef99e67e0ae58ebffbb7404 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 14 Jul 2026 14:41:02 -0700 Subject: [PATCH 2/2] fix(review): revert accidental repo-doc/repo-skill marker rename The AGENTS.md/skill-doc bracketing markers must stay byte-stable across a rebrand since a refresh matches on them literally; this batch's earlier commit renamed them by mistake. --- src/review/repo-doc-render.ts | 4 ++-- src/review/repo-skill-render.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/review/repo-doc-render.ts b/src/review/repo-doc-render.ts index c73a1f91a4..6e4533d756 100644 --- a/src/review/repo-doc-render.ts +++ b/src/review/repo-doc-render.ts @@ -14,8 +14,8 @@ import type { GeneratedDocMarkers } from "./generated-doc-refresh"; /** HTML-comment marker pair bracketing the machine-generated section of every AGENTS.md this engine writes. * Content outside this pair (added by a maintainer before the start marker or after the end marker) is treated * as permanently manual and is never touched by a refresh (#3004) -- see generated-doc-refresh.ts. */ -export const REPO_DOC_MARKER_START = ""; -export const REPO_DOC_MARKER_END = ""; +export const REPO_DOC_MARKER_START = ""; +export const REPO_DOC_MARKER_END = ""; export const REPO_DOC_MARKERS: GeneratedDocMarkers = { start: REPO_DOC_MARKER_START, end: REPO_DOC_MARKER_END }; const MAX_RENDERED_TOP_LEVEL_DIRECTORIES = 12; diff --git a/src/review/repo-skill-render.ts b/src/review/repo-skill-render.ts index d039ce3fd9..6cc14612e1 100644 --- a/src/review/repo-skill-render.ts +++ b/src/review/repo-skill-render.ts @@ -13,8 +13,8 @@ import type { RepoProfile, RepoProfileContributionWorkflow } from "./repo-profile"; import type { GeneratedDocMarkers } from "./generated-doc-refresh"; -export const REPO_SKILL_MARKER_START = ""; -export const REPO_SKILL_MARKER_END = ""; +export const REPO_SKILL_MARKER_START = ""; +export const REPO_SKILL_MARKER_END = ""; export const REPO_SKILL_MARKERS: GeneratedDocMarkers = { start: REPO_SKILL_MARKER_START, end: REPO_SKILL_MARKER_END }; function hasBlockingGate(contributionWorkflow: RepoProfileContributionWorkflow): boolean {