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
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"packages/loopover-mcp": "3.15.2",
"packages/loopover-engine": "3.16.0",
"packages/loopover-engine": "3.16.1",
"packages/loopover-miner": "3.15.2",
"packages/loopover-ui-kit": "1.2.0"
}
2 changes: 1 addition & 1 deletion packages/loopover-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@loopover/engine",
"version": "3.16.0",
"version": "3.16.1",
"license": "AGPL-3.0-only",
"type": "module",
"description": "Shared deterministic engine logic for the LoopOver review stack and loopover-miner.",
Expand Down
3 changes: 1 addition & 2 deletions packages/loopover-engine/src/advisory/gate-advisory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ import type {
AdvisoryFinding,
AdvisorySeverity,
GateRuleMode,
IssueRecord,
PullRequestRecord,
RepositoryRecord,
} from "../types/predicted-gate-types.js";
import type { CollisionReport } from "../types/predicted-gate-types.js";
import type { } from "../types/predicted-gate-types.js";
import { isDuplicateClusterWinnerByClaim } from "../signals/duplicate-winner.js";
import type { GuardrailPathMatch } from "../signals/change-guardrail.js";
import { nowIso } from "../utils/json.js";
Expand Down
5 changes: 0 additions & 5 deletions packages/loopover-engine/src/config-lint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ function recognizedFieldsFor(text: string | null | undefined): string[] {
);
}

// Fields retired from TOP_LEVEL_FIELDS that still warrant a migration-specific warning (rather than the
// generic "unknown field" message) pointing operators at their replacement mechanism.
const RETIRED_FIELD_MIGRATION_WARNINGS: Record<string, string> = {
blockedPaths: "blockedPaths is retired; use settings.hardGuardrailGlobs for path holds.",
};

// #9167: gate.mergeReadiness is a composite that only FILLS IN a sub-gate mode the operator left UNSET
// (src/rules/advisory.ts's applyMergeReadinessGate, and its engine twin) -- it never overrides an
Expand Down
6 changes: 1 addition & 5 deletions packages/loopover-engine/src/focus-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,21 @@ import { normalizeAutonomyPolicy, normalizeAutoMaintainPolicy } from "./settings
import { normalizeCommandAuthorizationPolicy } from "./settings/command-authorization.js";
import { normalizeContributorBlacklist } from "./settings/contributor-blacklist.js";
import { normalizeAutoCloseExemptLogins } from "./settings/auto-close-exempt.js";
import { DEFAULT_TYPE_LABELS, MAX_TYPE_LABEL_NAME_LENGTH, normalizeTypeLabelSet } from "./settings/pr-type-label.js";
import { MAX_TYPE_LABEL_NAME_LENGTH, normalizeTypeLabelSet } from "./settings/pr-type-label.js";
import {
DEFAULT_LINKED_ISSUE_LABEL_PROPAGATION,
normalizeLinkedIssueLabelPropagationConfig,
VALID_LINKED_ISSUE_LABEL_PROPAGATION_MODES,
} from "./review/linked-issue-label-propagation.js";
import {
DEFAULT_LINKED_ISSUE_HARD_RULES,
isLinkedIssueHardRuleMode,
normalizeLinkedIssueHardRulesConfig,
} from "./review/linked-issue-hard-rules-config.js";
import {
DEFAULT_UNLINKED_ISSUE_GUARDRAIL,
isUnlinkedIssueGuardrailMode,
normalizeUnlinkedIssueGuardrailConfig,
} from "./review/unlinked-issue-guardrail-config.js";
import { normalizeAdvisoryAiRoutingConfig } from "./review/advisory-ai-routing-config.js";
import {
DEFAULT_SCREENSHOT_TABLE_GATE,
isScreenshotTableGateAction,
normalizeScreenshotTableGateConfig,
} from "./review/screenshot-table-gate.js";
Expand Down
11 changes: 6 additions & 5 deletions packages/loopover-engine/src/scoring/preview.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ContributorEvidenceRecord, JsonValue, RepositoryRecord, RepoTimeDecayOverrides, ScoringModelSnapshotRecord, ScorePreviewRecord } from "./types.js";
import { DEFAULT_SCORING_CONSTANTS } from "./model.js";
import { hasUnsafeWildcardCount } from "../signals/change-guardrail.js";
import {
clearLabelPatternRegExpCacheForTest,
LABEL_PATTERN_REGEXP_CACHE_MAX_ENTRIES,
Expand All @@ -11,10 +10,12 @@ import {
// Deterministic score-preview builder extracted verbatim from the backend's `src/scoring/preview.ts`
// (#2282) — this file has no D1/network/env dependency in the original, so it ports unchanged aside from
// its imports and one tiny pure helper (`nowIso`) inlined below, which the backend sources from
// `src/utils/json.ts`. `hasUnsafeWildcardCount` is imported from this package's own
// `signals/change-guardrail.ts` (#4611) rather than re-derived here — that file is a verbatim port of the
// backend's `src/signals/change-guardrail.ts`, kept in sync by the engine-parity contract test, so importing
// it carries the same ReDoS-safety guarantee without a third hand-maintained copy.
// `src/utils/json.ts`.
//
// The ReDoS-safety guarantee this file used to claim via a direct `hasUnsafeWildcardCount` import (#4611) now
// arrives through `labelMatchesPattern` (./label-match.ts), which applies the same cap internally — the import
// here had been dead since 625e236b4 deduped this file's label matching onto that module. The guarantee is
// unchanged; only the route to it is, and stating the live route is the point of saying so at all.

// The package's tsconfig sets `types: []` (no ambient DOM/Node globals, keeping the engine's type surface
// independent of any consumer's lib config), so the Web Crypto global needs a minimal local declaration.
Expand Down
7 changes: 3 additions & 4 deletions packages/loopover-engine/src/signals/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,21 @@ import type {
ScoringModelSnapshotRecord,
} from "../../../../src/types.js";
import type { PublicContributorProfile } from "../../../../src/github/public.js";
import { commandReferenceUrl, loopoverFooter, gittensorRepoEarnUrl, type LoopOverFooterEnv } from "../../../../src/github/footer.js";
import { commandReferenceUrl, type LoopOverFooterEnv } from "../../../../src/github/footer.js";
import type { FocusManifestReviewConfig, ReviewFieldKey } from "../../../../src/signals/focus-manifest.js";
import type { GittensorContributorSnapshot } from "../../../../src/gittensor/api.js";
import { nowIso } from "../utils/json.js";
import { extractLinkedIssueNumbers } from "../../../../src/db/repositories.js";
import { sanitizePublicComment } from "../../../../src/queue-intelligence.js";
import { labelMatchesPattern, projectLinkedIssueMultiplierForPlannedSolve, type LinkedIssueMultiplierStatus } from "../scoring/preview.js";
import { isSuspiciousConfiguredLabel } from "../scoring/label-match.js";
import { hasLocalTestEvidence, hasValidationNote, isTestPath } from "./test-evidence.js";
import { hasLocalTestEvidence, hasValidationNote, } from "./test-evidence.js";
import { isCodeFile, isTestFile } from "./path-matchers.js";
import { isFailingCheckSummary } from "./check-summary.js";
import { isDuplicateClusterWinnerByClaim } from "./duplicate-winner.js";
import { PREFLIGHT_LIMITS } from "./preflight-limits.js";
import type { UnifiedCollapsible } from "../../../../src/review/unified-comment.js";
import { splitAiReviewNits } from "../../../../src/review/ai-notes.js";
import { LOOPOVER_GATE_CHECK_NAME, shouldPublishReviewCheck } from "../../../../src/review/check-names.js";
import { shouldPublishReviewCheck } from "../../../../src/review/check-names.js";
import { isAgentConfigured } from "../settings/autonomy.js";
import { diffFilePriority } from "../review/diff-file-priority.js";
import type { ImprovementBand, StructuralImprovementAssessment } from "../../../../src/signals/improvement.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type {
AdvisoryFinding,
BountyLifecycle,
BountyRecord,
CollisionCluster,
Expand Down Expand Up @@ -46,13 +45,6 @@ const STOPWORDS = new Set([
const MAX_COLLISION_PAIRWISE_ISSUES = 80;
const MAX_COLLISION_PAIRWISE_PULL_REQUESTS = 120;
const MAX_COLLISION_PAIRWISE_RECENT_MERGES = 40;
const ISSUE_DISCOVERY_LIFECYCLE_REPORT_CAP = 300;
const ISSUE_QUALITY_REPORT_CAP = 100;
const REPO_OUTCOME_STALE_OPEN_DAYS = 30;
const REPO_OUTCOME_MIN_DECIDED_SAMPLE = 3;
const REPO_OUTCOME_MERGE_WELL_RATE = 0.7;
const REPO_OUTCOME_CLOSURE_RISK_RATE = 0.34;
const REPO_OUTCOME_MAX_PATTERNS = 12;

export function buildLaneAdvice(repo: RepositoryRecord | null, fullName: string): LaneAdvice {
const config = repo?.registryConfig;
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-miner/expected-engine.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.16.0
3.16.1
2 changes: 1 addition & 1 deletion packages/loopover-miner/lib/cross-repo-evaluation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ function resolveEvaluationRepoPath(
return resolveRepoCloneDir(entry.repoFullName, options.env ?? process.env);
}

function defaultClaimLedger(repoFullName: string): { listClaims: () => never[] } {
function defaultClaimLedger(_repoFullName: string): { listClaims: () => never[] } {
return { listClaims: () => [] };
}

Expand Down
5 changes: 0 additions & 5 deletions packages/loopover-miner/lib/portfolio-queue-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ export type ParsedQueueClaimBatchArgs =
| { json: boolean; dryRun: boolean; globalWipCap: number; perRepoWipCap: number }
| { error: string };

type PortfolioQueueCliOptions = {
initPortfolioQueue?: () => PortfolioQueueStore;
initPortfolioQueueManager?: (opts: unknown) => PortfolioQueueManager;
nowMs?: number;
};

function parseRepoArg(value: string | undefined, usage: string): { error: string } | { repoFullName: string } {
if (!value) return { error: usage };
Expand Down
2 changes: 1 addition & 1 deletion scripts/replay-decision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ if (invokedDirectly) {
console.error("replay-decision: --at requires a Unix-epoch-milliseconds value");
process.exit(2);
}
const source = argv.filter((arg, index) => index !== atIndex && index !== atIndex + 1)[0];
const source = argv.filter((_arg, index) => index !== atIndex && index !== atIndex + 1)[0];
if (!source) {
console.error("usage: replay-decision.ts <bundle.json | -> [--at <epoch ms>]");
process.exit(2);
Expand Down
1 change: 0 additions & 1 deletion scripts/verify-attested-run-der.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const LONG_LENGTH_MASK = 0x80;
const LONG_LENGTH_COUNT_MASK = 0x7f;
const OID_ARC_CONTINUATION_BIT = 0x80;
const OID_ARC_VALUE_MASK = 0x7f;
const OID_ARC_SHIFT_BITS = 7;

/** One parsed DER TLV: `tag`, the byte range of its VALUE (not including the tag/length header), and (for a
* constructed tag -- SEQUENCE, SET, or a context-specific `[N]` wrapper) its immediate children, parsed one
Expand Down
43 changes: 2 additions & 41 deletions src/api/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { isScreenshotsEnabled } from "../review/visual-wire";
import { buildFindingTaxonomyDocument } from "../review/finding-taxonomy";
import { buildEnrichmentAnalyzersTaxonomyDocument } from "../review/enrichment-analyzers-taxonomy";
import {
BROWSER_SESSION_COOKIE,
GITHUB_OAUTH_STATE_COOKIE,
authenticateInternalToken,
authenticatePrivateToken,
Expand Down Expand Up @@ -39,13 +38,10 @@ import { SCENARIO_MAX_BRANCH_REF_CHARS, SCENARIO_MAX_LINKED_ISSUE_NUMBERS, SCENA
import {
countOpenIssues,
countOpenPullRequests,
countActiveAuthSessions,
countActiveDigestSubscriptions,
countRecentAuditEventsForActorAndTarget,
getBounty,
getAgentCommandAnswer,
getCommandUsefulnessSummary,
getFreshOfficialMinerDetection,
getIssue,
getInstallation,
getInstallationHealth,
Expand Down Expand Up @@ -110,11 +106,8 @@ import {
recordProductUsageEvent,
rollupProductUsageDaily,
summarizeMcpCompatibilityAdoption,
summarizeProductUsageEvents,
upsertDigestSubscription,
upsertBounty,
upsertContributorEvidence,
upsertContributorScoringProfile,
upsertRepositorySettings,
clearPullRequestsRegatedAtForOpenPrs,
getProviderCredentialStatus,
Expand Down Expand Up @@ -146,7 +139,7 @@ import {
import { getRepositoryCollaboratorPermission } from "../github/app";
import { performRepoDocRefresh } from "../github/repo-doc-refresh-runner";
import type { LoopOverFooterEnv } from "../github/footer";
import { contributorRepoStatsFromGittensor, fetchGittensorContributorSnapshot } from "../gittensor/api";
import { fetchGittensorContributorSnapshot } from "../gittensor/api";
import { fetchPublicContributorProfile, fetchPublicRepoStats } from "../github/public";
import {
buildPublicAgentCommandComment,
Expand Down Expand Up @@ -250,7 +243,6 @@ import { buildPublicRepoQuality, type PublicRepoQuality } from "../services/publ
import { loadPublicQualityMetrics } from "../services/public-quality-metrics";
import { buildShieldsBadge, LABEL as PUBLIC_BADGE_LABEL, renderBadgeSvg, renderUnavailableBadgeSvg } from "./badge";
import {
buildWeeklyValueReport,
formatWeeklyValueReportMarkdown,
generateWeeklyValueReport,
loadWeeklyValueReport,
Expand All @@ -265,7 +257,6 @@ import { loadOrComputeRepoOutcomePatternsResponse } from "../services/repo-outco
import { PREFLIGHT_LIMITS } from "../signals/preflight-limits";
import {
buildBountyAdvisory,
buildBurdenForecast,
buildCollisionReport,
buildConfigQuality,
buildContributorFit,
Expand All @@ -292,7 +283,7 @@ import { buildContributorPrOutcomes } from "../signals/contributor-pr-outcomes";
import { buildReviewRiskExplanation } from "../signals/review-risk";
import { buildNotificationFeed, evaluateAndEnqueueNotificationDeliveries } from "../notifications/service";
import { normalizeAmsNotificationEventInput } from "../notifications/ams-events";
import { buildPullRequestReviewability, type PullRequestReviewability } from "../signals/reward-risk";
import { buildPullRequestReviewability, } from "../signals/reward-risk";
import { buildLocalBranchAnalysis, findCurrentBranchPullRequest } from "../signals/local-branch";
import { buildIssueSlopAssessment } from "../signals/issue-slop";
import { buildSlopAssessment } from "../signals/slop";
Expand Down Expand Up @@ -347,7 +338,6 @@ import {
import { fileUpstreamDriftIssues, loadUpstreamStatus, refreshUpstreamDrift, registryHyperparameterDriftWarningsForRepo, resolveAutoFileDriftIssuesManifestOverride } from "../upstream/ruleset";
import type {
ControlPanelRoleName,
ContributorEvidenceRecord,
DataQuality,
InstallationHealthRecord,
JobMessage,
Expand Down Expand Up @@ -6413,35 +6403,6 @@ async function persistSignal(
});
}

function contributorEvidenceFromProfile(profile: {
login: string;
generatedAt: string;
evidence: {
registeredRepoPullRequests: number;
mergedPullRequests: number;
openPullRequests: number;
stalePullRequests: number;
unlinkedPullRequests: number;
issueDiscoveryReports: number;
languageMatches: number;
credibilityAssumption: number;
};
}): ContributorEvidenceRecord {
return {
login: profile.login,
generatedAt: profile.generatedAt,
payload: {
pullRequests: profile.evidence.registeredRepoPullRequests,
mergedPullRequests: profile.evidence.mergedPullRequests,
openPullRequests: profile.evidence.openPullRequests,
stalePullRequests: profile.evidence.stalePullRequests,
unlinkedPullRequests: profile.evidence.unlinkedPullRequests,
issueDiscoveryReports: profile.evidence.issueDiscoveryReports,
languageMatches: profile.evidence.languageMatches,
credibilityAssumption: profile.evidence.credibilityAssumption,
},
};
}

const OPPORTUNITIES_FIND_PATH = "/v1/opportunities/find";
const ISSUE_RAG_RETRIEVE_PATH = "/v1/issue-rag/retrieve";
Expand Down
2 changes: 1 addition & 1 deletion src/db/repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ import type { GittensorContributorSnapshot, OfficialGittensorMinerDetection } fr
import { classifyMcpClientVersion, LATEST_RECOMMENDED_MCP_VERSION, MINIMUM_SUPPORTED_MCP_VERSION } from "../services/mcp-compatibility";
import { DEFAULT_COMMAND_AUTHORIZATION_POLICY, normalizeCommandAuthorizationPolicy } from "../settings/command-authorization";
import { normalizeContributorBlacklist } from "../settings/contributor-blacklist";
import { DEFAULT_GLOBAL_MODERATION_CONFIG, MAX_MODERATION_VIOLATION_DECAY_DAYS, normalizeModerationLabel, normalizeModerationRules, type GlobalModerationConfig, type ModerationRuleType } from "../settings/moderation-rules";
import { DEFAULT_GLOBAL_MODERATION_CONFIG, MAX_MODERATION_VIOLATION_DECAY_DAYS, normalizeModerationLabel, normalizeModerationRules, type GlobalModerationConfig, } from "../settings/moderation-rules";
import { normalizeAutonomyPolicy, DEFAULT_AUTO_MAINTAIN_POLICY } from "../settings/autonomy";
import { DEFAULT_TYPE_LABELS } from "../settings/pr-type-label";
import { DEFAULT_LINKED_ISSUE_LABEL_PROPAGATION } from "../review/linked-issue-label-propagation";
Expand Down
1 change: 0 additions & 1 deletion src/github/backfill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import { agentRequiresContentsWrite, agentRequiresPrWrite } from "../settings/ag
import { resolveRepositorySettings } from "../settings/repository-settings";
import type {
ContributorRepoStatRecord,
GitHubRateLimitObservationRecord,
GitHubIssuePayload,
GitHubPullRequestPayload,
GitHubRepositoryPayload,
Expand Down
2 changes: 1 addition & 1 deletion src/github/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ async function fetchWithGitHubRetry(input: RequestInfo | URL, init?: GitHubTimeo
async function fetchAndMaybeCacheGitHubGet(
input: RequestInfo | URL,
init: GitHubTimeoutFetchInit | undefined,
url: string,
_url: string,
cacheKey: string,
cls: GitHubCacheClass,
): Promise<{ response: Response; cached: CachedGitHubResponse | null }> {
Expand Down
2 changes: 1 addition & 1 deletion src/mcp/dispatch-telemetry-sink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// schema is strict", and this Worker already bundles posthog-node for #6235, so there is no bundle
// argument for avoiding it here. (#9525's issue text assumed metagraphed's situation, where the
// bundle cost was real.)
import type { McpToolCallTelemetry } from "@loopover/contract";
import type { } from "@loopover/contract";
import { capturePostHogWorkerError, isWorkerPostHogConfigured, type WorkerPostHogEnv } from "../api/worker-posthog";
import { MCP_TOOL_CALL_EVENT, MCP_USAGE_EVENT } from "@loopover/contract";
import type { DispatchTelemetrySink } from "./dispatch-telemetry";
Expand Down
Loading