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
4 changes: 2 additions & 2 deletions packages/loopover-engine/src/advisory/gate-advisory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ export function evaluateGateCheck(advisoryResult: Advisory, policy: GateCheckPol

function evaluateGateCheckCore(advisoryResult: Advisory, policy: GateCheckPolicy = {}): GateCheckEvaluation {
const warnings = advisoryResult.findings.filter((finding) => finding.severity === "warning");
// App/infra state (repo not synced yet, PR not cached): gittensory cannot evaluate this PR yet, so the
// App/infra state (repo not synced yet, PR not cached): loopover cannot evaluate this PR yet, so the
// gate is NEUTRAL (non-blocking) and re-evaluates automatically on the next sync/webhook. Never block a
// contributor on the app's OWN state.
if (advisoryResult.findings.some((finding) => isEvaluationBlocker(finding.code, policy))) {
Expand Down Expand Up @@ -530,7 +530,7 @@ function evaluateGateCheckCore(advisoryResult: Advisory, policy: GateCheckPolicy

function isEvaluationBlocker(code: string, policy: GateCheckPolicy): boolean {
// pre_merge_check_unresolved: an enforced path-gated pre-merge check whose changed-file set could not be
// resolved — gittensory cannot evaluate it yet, so the gate is NEUTRAL (held) and re-evaluates on the next
// resolved — loopover cannot evaluate it yet, so the gate is NEUTRAL (held) and re-evaluates on the next
// sync, rather than auto-merging past the unverified requirement or hard-closing on a transient miss. (#review-audit)
if (code === "repo_not_registered" || code === "repo_not_seen" || code === "pr_not_cached" || code === "pre_merge_check_unresolved") return true;
// cla_check_unresolved (#2564): the CLA-bot check-run's conclusion could not be resolved. Unlike the codes
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/duplicate-winner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* caller can compute the winner ONCE per review run and thread the result boolean consistently into every
* surface (advisory finding, close reason, slop, panels), so they agree by construction.
*
* ELECTION ORDER: compare `linkedIssueClaimedAt`, the time gittensory first observed the PR claiming
* ELECTION ORDER: compare `linkedIssueClaimedAt`, the time loopover first observed the PR claiming
* the issue. GitHub `pull_request.created_at` is intentionally not an ordering signal here: contributors can
* edit an old placeholder PR to add a linked issue later, so creation time would let backdated claims steal
* duplicate-winner credit from the PR that actually claimed the issue first. Sparse legacy rows that lack
Expand Down
24 changes: 12 additions & 12 deletions packages/loopover-engine/src/focus-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,12 @@ export type ConvergedFeatureKey = (typeof CONVERGED_FEATURE_KEYS)[number];
* `LOOPOVER_REVIEW_REPOS` allowlist default, so an operator who sets nothing keeps today's behavior. */
export type FocusManifestFeaturesConfig = { present: boolean } & Record<ConvergedFeatureKey, boolean | null>;

/** Optional ecosystem/network integrations under the `experimental:` block — plugins that couple gittensory to
/** Optional ecosystem/network integrations under the `experimental:` block — plugins that couple loopover to
* an external system rather than core review behavior. Starts with `gittensor` (the subnet mining-registry/
* scoring integration gittensory originally shipped with); future plugins land in this same array as the
* scoring integration loopover originally shipped with); future plugins land in this same array as the
* product broadens beyond gittensor. Deliberately a SEPARATE block from `features:` (converged review
* capabilities) — an operator (especially self-host) should be able to see at a glance which toggles are "how
* gittensory reviews PRs" vs "which external network/ecosystem this instance opts into." */
* loopover reviews PRs" vs "which external network/ecosystem this instance opts into." */
export const EXPERIMENTAL_PLUGIN_KEYS = ["gittensor"] as const;
export type ExperimentalPluginKey = (typeof EXPERIMENTAL_PLUGIN_KEYS)[number];

Expand All @@ -277,7 +277,7 @@ export type FocusManifestExperimentalConfig = { present: boolean } & Record<Expe
/**
* Per-repo registry-review lane configuration (`contentLane:` block, #2435) — lets a self-hosted maintainer
* configure their OWN registry (structural file-scope patterns + entry-count cap + dedup fields) without a
* gittensory code change. `entryFileGlob` and `collectionField` are the two REQUIRED fields to build a usable
* loopover code change. `entryFileGlob` and `collectionField` are the two REQUIRED fields to build a usable
* spec; `present` is true only when both are set (a partial config degrades to "not configured," not a broken
* half-spec — see `parseContentLaneConfig`). `validatorId` optionally references a code-registered domain
* validator (`review/content-lane/spec-resolver.ts`'s `REGISTRY_VALIDATORS`); omitted ⇒ structural gating only
Expand Down Expand Up @@ -344,7 +344,7 @@ export type FocusManifestReviewRecapConfig = {
* under `maintainerRecap:`. Distinct from `reviewRecap:` above (that is the single-repo digest's own window/
* enable knob); this instead overrides the LOOPOVER_MAINTAINER_RECAP / LOOPOVER_RECAP_CADENCE env vars
* that gate the cron-scheduled cross-repo digest (buildMaintainerRecap, #2239 / #2248) — read from the
* gittensory self-repo's manifest (resolveLoopOverSelfRepoFullName), since the digest is an operator-level
* loopover self-repo's manifest (resolveLoopOverSelfRepoFullName), since the digest is an operator-level
* setting, not a per-contributor-repo one. Mirrors `reviewRecap:` exactly: no DB-backed counterpart, so the
* parsed value (or the default below when unset) IS the effective value. Not present (or present with no
* fields set) ⇒ the caller falls back to the env vars, byte-identical to before this override existed.
Expand Down Expand Up @@ -485,7 +485,7 @@ export const REVIEW_FINDING_SEVERITY_LADDER = ["critical", "major", "minor", "ni

/**
* Maintainer overrides for the public review-panel CONTENT, declared under `review:`. Customizes the
* panel without changing what gittensory measures: a custom public-safe footer lead line, a custom intro
* panel without changing what loopover measures: a custom public-safe footer lead line, a custom intro
* note, and per-row show/hide toggles. The Gittensor attribution + register link is ALWAYS appended to
* the footer regardless (the growth surface is preserved); maintainer text that fails the public-safe
* filter is dropped, never published.
Expand Down Expand Up @@ -812,7 +812,7 @@ export type VisualConfig = {
enabled: boolean | null;
/** `review.visual.theme_storage_key` (#4109): the `localStorage` key the capture pipeline ALSO forces
* `theme` into (plus a reload) before rendering, for a target whose theming reads an explicit stored
* preference instead of consulting `prefers-color-scheme` — verified (against gittensory-ui's own
* preference instead of consulting `prefers-color-scheme` — verified (against loopover-ui's own
* dark-mode-only build) that `emulateMediaFeatures` alone has zero effect on that class of app, since it
* only changes what CSS media queries / `matchMedia` report. null (default) ⇒ no `localStorage` write, no
* reload — byte-identical to today. Only takes effect when `themes` is also configured; the key name is
Expand Down Expand Up @@ -851,7 +851,7 @@ export type VisualPreviewConfig = {
export type VisualRoutesConfig = {
/** `review.visual.routes.paths`: an explicit, always-screenshotted route list. When non-empty, this
* REPLACES automatic file-to-route inference entirely — for repos whose routing convention isn't
* gittensory-ui's TanStack file-based one, an explicit list is simpler and more robust than trying to
* loopover-ui's TanStack file-based one, an explicit list is simpler and more robust than trying to
* infer one. Empty (default) ⇒ automatic inference (falling back to "/" when nothing matches). */
paths: string[];
/** `review.visual.routes.max_routes`: overrides the built-in cap (2) on how many routes get screenshotted
Expand Down Expand Up @@ -1547,7 +1547,7 @@ export function featuresConfigToJson(features: FocusManifestFeaturesConfig): Jso
/**
* Parse the optional `experimental:` mapping — per-repo activation for optional ecosystem/network plugins
* (starting with `gittensor`, the subnet mining/scoring integration). Mirrors parseFeaturesConfig's shape and
* validation; kept as a SEPARATE top-level block from `features:` so plugin integrations that couple gittensory
* validation; kept as a SEPARATE top-level block from `features:` so plugin integrations that couple loopover
* to an external network stay visibly distinct from the converged REVIEW capabilities `features:` toggles, and
* so future plugins land in the same place without touching `features:`'s semantics.
*/
Expand Down Expand Up @@ -2185,7 +2185,7 @@ function parseSettingsOverride(value: JsonValue | undefined, warnings: string[])
const moderationBannedLabel = normalizeModerationLabel(r.moderationBannedLabel);
if (moderationBannedLabel !== undefined) out.moderationBannedLabel = moderationBannedLabel;
// Review-evasion protection (#review-evasion-protection): a contributor closing/converting-to-draft their
// own PR while gittensory has an active review pass running is dodging the one-shot review.
// own PR while loopover has an active review pass running is dodging the one-shot review.
const reviewEvasionProtection = normalizeOptionalEnum(r.reviewEvasionProtection, "settings.reviewEvasionProtection", ["off", "close"] as const, warnings);
if (reviewEvasionProtection !== null) out.reviewEvasionProtection = reviewEvasionProtection;
// #label-scoping: same load-bearing-null idiom as blacklistLabel above.
Expand Down Expand Up @@ -3114,7 +3114,7 @@ export function parseFocusManifest(raw: unknown, source?: FocusManifestSource):

/**
* Parse raw manifest file/record content (JSON or YAML). Malformed content degrades to an empty
* manifest with a warning rather than throwing, so a broken `.gittensory` config never breaks analysis.
* manifest with a warning rather than throwing, so a broken `.loopover` config never breaks analysis.
*/
export function parseFocusManifestContent(content: string | null | undefined, source: FocusManifestSource = "repo_file"): FocusManifest {
if (content === undefined || content === null || content.trim() === "") return emptyManifest(source);
Expand Down Expand Up @@ -3163,7 +3163,7 @@ function normalizePathForMatch(path: string): string {

/**
* LINEAR-TIME wildcard matcher for a `*`-glob pattern over an already-normalized path. `*` (and a collapsed
* run of `*`) matches any run of characters INCLUDING `/` (gittensory globs cross slashes). Implemented as a
* run of `*`) matches any run of characters INCLUDING `/` (loopover globs cross slashes). Implemented as a
* prefix + suffix + ordered-substring (indexOf) scan rather than a `.*`-per-star regex: the old regex
* (`^.*a.*a...$`) backtracks catastrophically on a near-miss path and could hang the gate for an entire repo
* (a manifest glob with many non-adjacent `*`). This algorithm is O(path × parts) with NO backtracking.
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/focus-manifest/guidance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function normalizePathForMatch(path: string): string {

/**
* LINEAR-TIME wildcard matcher for a `*`-glob pattern over an already-normalized path. `*` (and a collapsed
* run of `*`) matches any run of characters INCLUDING `/` (gittensory globs cross slashes). Implemented as a
* run of `*`) matches any run of characters INCLUDING `/` (loopover globs cross slashes). Implemented as a
* prefix + suffix + ordered-substring (indexOf) scan rather than a `.*`-per-star regex: the old regex
* (`^.*a.*a...$`) backtracks catastrophically on a near-miss path and could hang the gate for an entire repo
* (a manifest glob with many non-adjacent `*`). This algorithm is O(path × parts) with NO backtracking.
Expand Down
6 changes: 3 additions & 3 deletions packages/loopover-engine/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Barrel export for @loopover/engine.
//
// This package houses the deterministic, side-effect-free logic shared by the LoopOver review-stack
// backend and the gittensory-miner (scoring preview/model, predicted-gate types, reward-risk, slop signals,
// backend and the loopover-miner (scoring preview/model, predicted-gate types, reward-risk, slop signals,
// focus-manifest parse/compile core, duplicate-winner adjudication, and their engine-parity fixtures).
// More modules land in follow-up issues.
export { ENGINE_VERSION } from "./version.js";
Expand Down Expand Up @@ -193,7 +193,7 @@ export {
type AcceptanceCriteria,
type AcceptanceCriteriaInput,
} from "./miner/acceptance-criteria.js";
// Pure deny-hook evaluator + rule-proposal synthesis moved out of gittensory-miner (#5667). The miner-lib
// Pure deny-hook evaluator + rule-proposal synthesis moved out of loopover-miner (#5667). The miner-lib
// `deny-hooks.js`/`deny-hook-synthesis.js` are now thin wrappers over these (the SQLite proposal store stays in
// the miner). `synthesizeDenyRuleProposals` takes an injected `nowMs` clock so synthesis is deterministic/pure.
export {
Expand Down Expand Up @@ -775,7 +775,7 @@ export {
} from "./reward-risk.js";

// Shared subprocess env-allowlist + secret-redaction helpers (#4284) — one source of truth for every driver that
// spawns a locally-authenticated CLI subprocess (src/selfhost/ai.ts and the coming gittensory-miner drivers).
// spawns a locally-authenticated CLI subprocess (src/selfhost/ai.ts and the coming loopover-miner drivers).
export {
SUBPROCESS_CLI_ENV_ALLOWLIST,
buildAllowlistedEnv,
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/issue-rag-query.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Issue-centric RAG query composition (#2320), extracted from `src/review/issue-rag-wire.ts` (#4254) so the
// gittensory-miner analyze phase can build the identical retrieval query without importing the review stack.
// loopover-miner analyze phase can build the identical retrieval query without importing the review stack.
// Pure, string-only: the miner has no PR diff yet, so retrieval is fed from the issue's title/body/labels
// while the RAG engine itself stays unchanged (retrieveContext remains Vectorize/D1-bound in `src/review/rag.ts`
// and is intentionally NOT part of this module).
Expand Down
4 changes: 2 additions & 2 deletions packages/loopover-engine/src/local-scorer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// #782 deterministic local scorer, extracted from src/signals/local-scorer.ts (#4253) so the published
// gittensory-mcp / gittensory-miner CLIs and the hosted Worker share one implementation. Replicates the
// loopover-mcp / loopover-miner CLIs and the hosted Worker share one implementation. Replicates the
// gittensor-root token-scoring view from changed-file METADATA (paths + line counts) — never source content,
// so the no-upload boundary holds and it runs in every surface. It mirrors buildScorePreview's
// source/test/non-code classification, so feeding its output back in as `localScorer` (mode external_command)
Expand Down Expand Up @@ -56,7 +56,7 @@ export function computeLocalScorerTokens(input: { changedFiles: LocalScorerChang
const warnings = failed ? ["Local validation reported failures — token scores describe the diff, not a passing build."] : [];
return {
mode: "external_command",
activeModel: "gittensory-deterministic",
activeModel: "loopover-deterministic",
sourceTokenScore,
totalTokenScore,
sourceLines: Math.max(1, sourceTokenScore || totalTokenScore || 1),
Expand Down
4 changes: 2 additions & 2 deletions packages/loopover-engine/src/miner-prediction-metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
// prediction-ledger rows (packages/loopover-miner/lib/prediction-ledger.js `readPredictions`) — optionally
// joined with their realized outcome — into counters a future dashboard can scrape.
//
// Scoped as an on-demand RENDERER, not a live HTTP registry: gittensory-miner is a local CLI, not a daemon, so a
// Scoped as an on-demand RENDERER, not a live HTTP registry: loopover-miner is a local CLI, not a daemon, so a
// caller renders this to stdout for its own scrape/cron setup and reads the ledger itself (no data collection of
// its own lives here — this stays a pure, side-effect-free function like the rest of gittensory-engine). It mirrors
// its own lives here — this stays a pure, side-effect-free function like the rest of loopover-engine). It mirrors
// the metric-naming (`loopover_miner_*_total`) and HELP/TYPE/label conventions of src/selfhost/metrics.ts rather
// than importing across the package boundary.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { FeasibilityGateResult, FeasibilityVerdict } from "../feasibility.j
// agent "boundary membrane") and the `FeasibilityGateResult` go/raise/avoid verdict (feasibility.ts) — into one
// document. Producing the document is this module's job; actually writing it into the attempt's worktree is the
// worktree primitive's (#4269), and handing it to the driver is the driver interface's (#4262) — neither is here,
// so this stays pure and side-effect-free like the rest of gittensory-engine.
// so this stays pure and side-effect-free like the rest of loopover-engine.
//
// DECISIONS this file makes (per the issue's open questions):
// - Serialization format: JSON, not markdown. The acceptance criteria are an immutable, checksum-verifiable success
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/miner/attempt-log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export function formatAttemptLogJsonl(events: readonly NormalizedAttemptLogEvent
return events.map((event) => JSON.stringify(event)).join("\n");
}

/** In-memory appender for tests and local tooling — production persistence uses `gittensory-miner/lib/attempt-log.js`. */
/** In-memory appender for tests and local tooling — production persistence uses `loopover-miner/lib/attempt-log.js`. */
export function createAttemptLogBuffer(): {
append: (event: AttemptLogEvent) => NormalizedAttemptLogEvent;
events: () => readonly NormalizedAttemptLogEvent[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { buildAllowlistedEnv, redactSecrets } from "../subprocess-env.js";

// CLI-subprocess CodingAgentDriver (#4266). Implements the CodingAgentDriver seam (#4262) by running the coding
// agent (`claude`/`codex`) as a subprocess in the attempt's scoped working directory. The spawn primitive is
// INJECTED (a generalized version of src/selfhost/ai.ts's SpawnFn, redeclared here so gittensory-engine stays
// INJECTED (a generalized version of src/selfhost/ai.ts's SpawnFn, redeclared here so loopover-engine stays
// standalone and doesn't import from src/), so the driver is fully testable without a real child process. Two
// safety primitives are reused from subprocess-env.ts (#4284) rather than re-implemented: the child gets a STRICT
// allowlisted env (never the full host env — a coding-agent subprocess is prompt-injectable), and any subprocess
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/miner/iterate-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// from the loop MECHANICS (#2333) so the actual thresholds/rules are one small, individually-reviewable, pure
// artifact -- `decideNextAction` needs no driver, no worktree, no IO to test.
//
// STRATEGIC CONSTRAINTS this policy encodes (gittensory-miner-autonomy-roadmap):
// STRATEGIC CONSTRAINTS this policy encodes (loopover-miner-autonomy-roadmap):
// - "never auto-submit (P4) before governor+caps (P5)" -- a mandatory clean predicted-gate PASS is the ONLY
// path to `"handoff"`; an ambiguous or errored self-review downgrades to abandon, never optimistically
// hands off.
Expand Down
Loading