From 99022f9c8a555d3fff12079d36ddbcfcddc67504 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 28 Jul 2026 03:23:31 -0700 Subject: [PATCH 1/5] build(typescript): enable noUnusedLocals/noUnusedParameters repo-wide (#9553) Dead code is the substrate every drift bug in the 2026-07-27 audit grew on: a stale import or an orphaned constant reads exactly like a live wire, so the next person greps, finds it, and reasons about a code path that no longer runs. Enabling the flags made the compiler enumerate all 515 instances. Every one in src/** and packages/** was traced to its replacement before deletion -- all 82 were genuine supersession leftovers, no behaviour bug hiding among them -- but the triage turned up three real problems that were invisible under the noise: 1. src/queue/processors.ts -- sweepRepoBacklogConvergence accepted `requestedBy` ("schedule" | "api" | "test") and dropped it. Every sibling sweep stamps it into recordAuditEvent's metadata; both agent.sweep.backlog_convergence events here omitted it, so those records could not be attributed to a schedule vs a manual API trigger. Now wired into both. (Note the mechanical fix would have been to rename it `_requestedBy`, which cements the gap instead of closing it.) 2. test/unit/openapi.test.ts -- the #9302 REST<->MCP parity guard asserted against src/mcp/server.ts's gatePrecisionOutputSchema and maintainerMeasurementReportOutputSchema, which the tools stopped registering when #9518 moved their outputs to @loopover/contract. The shapes are still identical, so nothing had drifted YET -- but the guard was watching objects no runtime reads and would not have caught a future contract change. Re-anchored onto GetGatePrecisionOutput.shape / GetOutcomeCalibrationOutput.shape, which is what the tools actually register, and what that file's own header comment already claimed it did. 3. src/github/resolve-command.ts was reachable only from its own test, because src/review/review-memory-wire.ts carried a SECOND byte-identical copy of normalizeResolveFindingRef (regex included) and that copy was the one production used. Two independent implementations of the same public-safety validation, free to drift. Deduped onto the original via re-export; dead-source-files:check now passes on a file it was about to start failing on. Also corrects packages/loopover-engine/src/scoring/preview.ts's header, which claimed a ReDoS guarantee via a hasUnsafeWildcardCount import that had been dead since 625e236b4 deduped its label matching onto label-match.ts. The guarantee is real and unchanged; it now arrives through labelMatchesPattern, and the comment says so. Pre-existing import-specifier violations fixed in the same pass, since the tree has to be green for the flags to mean anything: - scripts/actionlint.ts imported a `.ts` specifier (TS5097) - test/unit/contract-registry.test.ts had three `.js` specifiers in a Bundler zone - check-dead-source-files-script.test.ts tripped check-import-specifiers on its own string FIXTURES, the same self-referential false positive that checker's ALLOWED_FILENAMES already documents for its own test Mechanics: unused parameters are renamed with a leading underscore, never deleted -- they are positional, so removing one silently re-binds every later argument. Everything else was removed by its real TypeScript AST node span (a regex pass was tried first and mis-bounded declarations badly enough to produce unparseable files). Full suite green: 23,894 passed, 0 failed. tsc clean with the flags on. --- .../src/advisory/gate-advisory.ts | 3 +- packages/loopover-engine/src/config-lint.ts | 5 - .../loopover-engine/src/focus-manifest.ts | 6 +- .../loopover-engine/src/scoring/preview.ts | 11 +- .../loopover-engine/src/signals/engine.ts | 7 +- .../src/signals/predicted-gate-engine.ts | 8 -- .../lib/cross-repo-evaluation.ts | 2 +- .../loopover-miner/lib/portfolio-queue-cli.ts | 5 - scripts/actionlint.ts | 2 +- scripts/replay-decision.ts | 2 +- scripts/verify-attested-run-der.ts | 1 - src/api/routes.ts | 43 +----- src/db/repositories.ts | 2 +- src/github/backfill.ts | 1 - src/github/client.ts | 2 +- src/mcp/server.ts | 118 +-------------- src/queue/processors.ts | 17 +-- src/review/pr-reconciliation.ts | 2 +- src/review/rag-index.ts | 4 +- src/review/rag-wire.ts | 2 +- src/review/review-memory-wire.ts | 8 +- src/selfhost/pg-queue.ts | 1 - src/selfhost/sqlite-queue.ts | 1 - src/server.ts | 1 - src/services/agent-orchestrator.ts | 2 +- src/services/decision-pack.ts | 2 +- src/signals/focus-manifest.ts | 1 - test/integration/api.test.ts | 2 +- test/unit/agent-orchestrator.test.ts | 1 - test/unit/ai-review.test.ts | 2 +- test/unit/backfill-2.test.ts | 76 ---------- test/unit/backfill.test.ts | 12 +- .../content-lane-netuid-verification.test.ts | 2 +- .../unit/content-lane-source-evidence.test.ts | 2 +- .../discovery-index/upload-sourcemaps.test.ts | 12 +- test/unit/federated-bundle.test.ts | 4 +- test/unit/focus-manifest-loader.test.ts | 1 - test/unit/governor-write-rate-limit.test.ts | 2 +- test/unit/knob-loosening-run.test.ts | 2 +- ...nked-issue-label-propagation-fetch.test.ts | 10 -- .../linked-issue-satisfaction-run.test.ts | 6 - .../lint-composite-actions-script.test.ts | 4 +- test/unit/maintainer-recap-wire.test.ts | 2 +- test/unit/maintainer-recap.test.ts | 2 +- test/unit/mcp-cli-validate-config.test.ts | 2 +- .../miner-ams-eligibility-backtest.test.ts | 2 +- test/unit/miner-attempt-cli.test.ts | 1 - test/unit/miner-ci-poller.test.ts | 2 +- ...-discover-cli-eligibility-metadata.test.ts | 5 - test/unit/miner-discover-cli.test.ts | 7 +- test/unit/miner-metrics-cli.test.ts | 5 - test/unit/openapi.test.ts | 15 +- .../unit/opportunity-metadata-signals.test.ts | 1 - test/unit/ops-wire.test.ts | 2 - test/unit/orb-analytics.test.ts | 2 +- test/unit/parity-wire.test.ts | 2 +- test/unit/patchless-secret-scan.test.ts | 1 - test/unit/pr-labeled-public-surface.test.ts | 2 +- test/unit/predicted-gate-engine.test.ts | 4 - test/unit/queue-2.test.ts | 91 +----------- test/unit/queue-3.test.ts | 135 ++---------------- test/unit/queue-4.test.ts | 79 +--------- test/unit/queue-5.test.ts | 110 ++------------ test/unit/queue-lifecycle-guards.test.ts | 135 ++---------------- test/unit/queue.test.ts | 74 ++-------- .../review-evasion-per-repo-admin.test.ts | 8 -- test/unit/review-grounding.test.ts | 1 - test/unit/routes-issue-plan-draft.test.ts | 2 +- ...screenshot-evidence-summary-wiring.test.ts | 3 +- test/unit/selfhost-pg-queue.test.ts | 2 +- test/unit/selfhost-pg-vectorize.test.ts | 2 +- .../selfhost-redis-response-cache.test.ts | 2 +- test/unit/signals-edge-cases.test.ts | 1 - test/unit/signals.test.ts | 14 +- tsconfig.json | 8 ++ 75 files changed, 137 insertions(+), 984 deletions(-) diff --git a/packages/loopover-engine/src/advisory/gate-advisory.ts b/packages/loopover-engine/src/advisory/gate-advisory.ts index 6cddfdbfe4..dd47b4adb4 100644 --- a/packages/loopover-engine/src/advisory/gate-advisory.ts +++ b/packages/loopover-engine/src/advisory/gate-advisory.ts @@ -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"; diff --git a/packages/loopover-engine/src/config-lint.ts b/packages/loopover-engine/src/config-lint.ts index 98efa5fec5..07ee999964 100644 --- a/packages/loopover-engine/src/config-lint.ts +++ b/packages/loopover-engine/src/config-lint.ts @@ -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 = { - 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 diff --git a/packages/loopover-engine/src/focus-manifest.ts b/packages/loopover-engine/src/focus-manifest.ts index 80d4b993cb..c2a545c67c 100644 --- a/packages/loopover-engine/src/focus-manifest.ts +++ b/packages/loopover-engine/src/focus-manifest.ts @@ -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"; diff --git a/packages/loopover-engine/src/scoring/preview.ts b/packages/loopover-engine/src/scoring/preview.ts index 7b93d7b689..315c080b6d 100644 --- a/packages/loopover-engine/src/scoring/preview.ts +++ b/packages/loopover-engine/src/scoring/preview.ts @@ -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, @@ -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. diff --git a/packages/loopover-engine/src/signals/engine.ts b/packages/loopover-engine/src/signals/engine.ts index 9c8df56fac..fce9b8c0e3 100644 --- a/packages/loopover-engine/src/signals/engine.ts +++ b/packages/loopover-engine/src/signals/engine.ts @@ -25,7 +25,7 @@ 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"; @@ -33,14 +33,13 @@ 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"; diff --git a/packages/loopover-engine/src/signals/predicted-gate-engine.ts b/packages/loopover-engine/src/signals/predicted-gate-engine.ts index 7360d4ed22..4a776ec664 100644 --- a/packages/loopover-engine/src/signals/predicted-gate-engine.ts +++ b/packages/loopover-engine/src/signals/predicted-gate-engine.ts @@ -1,5 +1,4 @@ import type { - AdvisoryFinding, BountyLifecycle, BountyRecord, CollisionCluster, @@ -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; diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.ts b/packages/loopover-miner/lib/cross-repo-evaluation.ts index 2e4512c915..ae3d4b87cf 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.ts +++ b/packages/loopover-miner/lib/cross-repo-evaluation.ts @@ -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: () => [] }; } diff --git a/packages/loopover-miner/lib/portfolio-queue-cli.ts b/packages/loopover-miner/lib/portfolio-queue-cli.ts index 599607d782..f500e69e6b 100644 --- a/packages/loopover-miner/lib/portfolio-queue-cli.ts +++ b/packages/loopover-miner/lib/portfolio-queue-cli.ts @@ -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 }; diff --git a/scripts/actionlint.ts b/scripts/actionlint.ts index 124ae067b0..83a54d6779 100644 --- a/scripts/actionlint.ts +++ b/scripts/actionlint.ts @@ -2,7 +2,7 @@ import { readFileSync, readdirSync } from "node:fs"; import { createRequire } from "node:module"; import { join } from "node:path"; import { setTimeout as delay } from "node:timers/promises"; -import { resolveActionlintDownloadAttempts } from "./lib/actionlint-download-attempts.ts"; +import { resolveActionlintDownloadAttempts } from "./lib/actionlint-download-attempts"; import type { ActionlintOptions, ActionlintResult } from "github-actionlint"; import type { Result } from "@tktco/node-actionlint/build/types.js"; diff --git a/scripts/replay-decision.ts b/scripts/replay-decision.ts index a8246173f0..fbe4b76715 100644 --- a/scripts/replay-decision.ts +++ b/scripts/replay-decision.ts @@ -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 [--at ]"); process.exit(2); diff --git a/scripts/verify-attested-run-der.ts b/scripts/verify-attested-run-der.ts index 4273691fef..ea8c2be381 100644 --- a/scripts/verify-attested-run-der.ts +++ b/scripts/verify-attested-run-der.ts @@ -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 diff --git a/src/api/routes.ts b/src/api/routes.ts index bf3bc3858d..86fa2ba8ff 100644 --- a/src/api/routes.ts +++ b/src/api/routes.ts @@ -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, @@ -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, @@ -110,11 +106,8 @@ import { recordProductUsageEvent, rollupProductUsageDaily, summarizeMcpCompatibilityAdoption, - summarizeProductUsageEvents, upsertDigestSubscription, upsertBounty, - upsertContributorEvidence, - upsertContributorScoringProfile, upsertRepositorySettings, clearPullRequestsRegatedAtForOpenPrs, getProviderCredentialStatus, @@ -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, @@ -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, @@ -265,7 +257,6 @@ import { loadOrComputeRepoOutcomePatternsResponse } from "../services/repo-outco import { PREFLIGHT_LIMITS } from "../signals/preflight-limits"; import { buildBountyAdvisory, - buildBurdenForecast, buildCollisionReport, buildConfigQuality, buildContributorFit, @@ -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"; @@ -347,7 +338,6 @@ import { import { fileUpstreamDriftIssues, loadUpstreamStatus, refreshUpstreamDrift, registryHyperparameterDriftWarningsForRepo, resolveAutoFileDriftIssuesManifestOverride } from "../upstream/ruleset"; import type { ControlPanelRoleName, - ContributorEvidenceRecord, DataQuality, InstallationHealthRecord, JobMessage, @@ -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"; diff --git a/src/db/repositories.ts b/src/db/repositories.ts index 1b35d39898..edfc08f76a 100644 --- a/src/db/repositories.ts +++ b/src/db/repositories.ts @@ -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"; diff --git a/src/github/backfill.ts b/src/github/backfill.ts index 278e79d5f8..00c6b9d28a 100644 --- a/src/github/backfill.ts +++ b/src/github/backfill.ts @@ -45,7 +45,6 @@ import { agentRequiresContentsWrite, agentRequiresPrWrite } from "../settings/ag import { resolveRepositorySettings } from "../settings/repository-settings"; import type { ContributorRepoStatRecord, - GitHubRateLimitObservationRecord, GitHubIssuePayload, GitHubPullRequestPayload, GitHubRepositoryPayload, diff --git a/src/github/client.ts b/src/github/client.ts index c08ee76498..13af732d1c 100644 --- a/src/github/client.ts +++ b/src/github/client.ts @@ -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 }> { diff --git a/src/mcp/server.ts b/src/mcp/server.ts index abd16b5754..333086bc3d 100644 --- a/src/mcp/server.ts +++ b/src/mcp/server.ts @@ -93,7 +93,6 @@ import { GetPrMaintainerPacketOutput, LintPrTextInput, LintPrTextOutput, - ExplainScoreBreakdownInput, ExplainScoreBreakdownOutput, ExplainReviewRiskInput, ExplainReviewRiskOutput, @@ -231,7 +230,6 @@ import { import { canLoginAccessRepo, canWatchRepo, loadControlPanelAccessScope, loadControlPanelRoleSummary, type ControlPanelAccessScope } from "../services/control-panel-roles"; import { countOpenIssues, - countPendingAgentActions, countOpenPullRequests, createPendingAgentActionIfAbsent, getBounty, @@ -240,14 +238,12 @@ import { listBountyLifecycleEvents, getContributorEvidence, getLatestRepoGithubTotalsSnapshot, - getInstallation, getIssue, getPendingAgentAction, getPullRequest, getRepository, getRepositorySettings, getLatestUpstreamRulesetSnapshot, - isGlobalAgentFrozen, getRepoQueueTrendSnapshot, listAgentAuditEvents, listCheckSummaries, @@ -284,7 +280,7 @@ import { decidePendingAgentAction } from "../services/agent-approval-queue"; import { automationStateSummary, buildAutomationState } from "../services/automation-state"; import { nowIso } from "../utils/json"; import { buildNotificationFeed } from "../notifications/service"; -import { contributorRepoStatsFromGittensor, fetchGittensorContributorSnapshot } from "../gittensor/api"; +import { fetchGittensorContributorSnapshot } from "../gittensor/api"; import { getRepositoryCollaboratorPermission } from "../github/app"; import { performRepoDocRefresh } from "../github/repo-doc-refresh-runner"; import { generateContributorIssueDrafts } from "../services/contributor-issue-draft"; @@ -352,7 +348,7 @@ import { buildQueueHealth, buildRegistryChangeReport, } from "../signals/engine"; -import { PUBLIC_SURFACE_SKIP_REASONS, skippedPrAuditRemediation, type PublicSurfaceSkipReason } from "../signals/settings-preview"; +import { skippedPrAuditRemediation, type PublicSurfaceSkipReason } from "../signals/settings-preview"; import { buildContributorOpenPrMonitor } from "../signals/contributor-open-pr-monitor"; import { buildContributorPrOutcomes } from "../signals/contributor-pr-outcomes"; import { buildReviewRiskExplanation } from "../signals/review-risk"; @@ -375,11 +371,9 @@ import { // silently-dead-feature shape this audit's check-dead-source-files.ts now guards against. Wired up here, // following the identical local-write-tools pattern every sibling in this block already uses. import { buildSoftClaimSpec } from "../miner/soft-claim"; -import { buildTestEvidenceReport, classifyTestCoverage, hasLocalTestEvidence, isCodeFile, isTestPath, TEST_FRAMEWORKS } from "../signals/test-evidence"; +import { buildTestEvidenceReport, } from "../signals/test-evidence"; import { applyStepResult, buildPlanDag, nextReadySteps, planProgress, validatePlanDag, type PlanDag } from "../services/plan-dag"; import { buildFocusManifestValidation } from "../services/focus-manifest-validation"; -import { isGlobalAgentPause, resolveAgentActionMode, resolveAgentPermissionReadiness } from "../settings/agent-execution"; -import { AUTONOMY_LEVELS } from "../settings/autonomy"; import { resolveRepositorySettings } from "../settings/repository-settings"; import { isDuplicateWinnerEnabledGlobally, resolveDuplicateWinnerEnabled } from "../settings/duplicate-winner-mode"; import { compileFocusManifestPolicy, MAX_FOCUS_MANIFEST_BYTES } from "../signals/focus-manifest"; @@ -433,11 +427,6 @@ const ownerRepoPullShape = { number: z.number().int().positive(), }; -const ownerRepoWindowShape = { - owner: z.string().min(1), - repo: z.string().min(1), - windowDays: z.number().int().positive().optional(), -}; // (#8660) write-side mirror of DELETE /v1/repos/:owner/:repo/selftune/overrides. `confirm` is the required @@ -465,13 +454,6 @@ const fileIncidentReportShape = { }; -const fleetAnalyticsOutputSchema = { - windowDays: z.number().optional(), - instanceCount: z.number().optional(), - fleet: z.unknown().optional(), - instances: z.array(z.unknown()).optional(), - outliers: z.array(z.unknown()).optional(), -}; const issueRagShape = { @@ -621,18 +603,6 @@ const generateContributorIssueDraftsShape = { limit: z.number().int().min(1).max(20).optional().default(5), }; -const generateContributorIssueDraftsOutputSchema = { - repoFullName: z.string(), - generatedAt: z.string(), - dryRun: z.boolean(), - createRequested: z.boolean(), - proposed: z.number(), - skippedDuplicate: z.number(), - skippedDeclined: z.number(), - skippedUnsafe: z.number(), - created: z.number(), - skippedCreateFailed: z.number(), -}; // #7426: dryRun/create/limit mirror generateContributorIssueDraftsShape's own bounds/defaults (create alone is // rejected -- the handler re-applies the explicit_create_requires_dry_run_false guard). `limit` is capped lower @@ -656,38 +626,6 @@ const planRepoIssuesShape = { milestone: planRepoIssuesMilestoneShape.optional(), }; -const planRepoIssuesOutputSchema = { - repoFullName: z.string(), - generatedAt: z.string(), - status: z.string(), - dryRun: z.boolean(), - createRequested: z.boolean(), - proposed: z.number(), - skippedDuplicate: z.number(), - skippedDeclined: z.number(), - skippedUnsafe: z.number(), - created: z.number(), - skippedCreateFailed: z.number(), - // Unlike generateContributorIssueDraftsOutputSchema, this INCLUDES each draft's title/body/labels: the content - // is generated fresh from the caller's own goal for their own repo (no loopover-internal signal to scrub), and - // the whole point of the dry-run-by-default posture is letting a maintainer actually read the proposal before - // deciding to create it. - drafts: z - .array( - z.object({ - title: z.string(), - body: z.string(), - labels: z.array(z.string()), - status: z.string(), - issueNumber: z.number().optional(), - issueUrl: z.string().optional(), - }), - ) - .optional(), - // Set only when a milestone target was given AND creation actually ran AND resolution succeeded (#7427) -- - // absent on a dry run, no milestone requested, or a degraded (failed) resolution. - milestoneNumber: z.number().optional(), -}; // #784 (MCP slice) — the agent audit feed: executed actions + approval decisions for a repo. @@ -798,23 +736,6 @@ const variantsShape = { variants: z.array(z.object(scorePreviewShape)).min(1).max(10), }; -// ── MCP tool output schemas ──────────────────────────────────────────────── -// Structured-output metadata for machine-readable tools so modern MCP clients -// can discover and validate LoopOver responses. Schemas declare documented -// top-level fields; complex/nullable/variant fields use a permissive type so -// validation never rejects a real response (the SDK strips unknown keys). All -// fields are optional because several tools return either a result payload or a -// `{ status: "not_found" | ... }` / refresh envelope. -const repoContextOutputSchema = { - repoFullName: z.string().optional(), - repo: z.unknown().optional(), - lane: z.unknown().optional(), - queueHealth: z.unknown().optional(), - queueTrends: z.unknown().optional(), - collisions: z.unknown().optional(), - configQuality: z.unknown().optional(), - dataQuality: z.unknown().optional(), -}; export const maintainerMeasurementReportOutputSchema = { @@ -875,12 +796,6 @@ const checkSlopRiskShape = { issueDiscoveryLane: z.boolean().optional(), }; -const checkSlopRiskOutputSchema = { - slopRisk: z.number().optional(), - band: z.enum(["clean", "low", "elevated", "high"]).optional(), - findings: z.unknown().optional(), - rubric: z.string().optional(), -}; // Idea-intake bridge input (#4798, spec #4779). Fields are loose here so the engine's validateIdeaSubmission // owns the real bounds/format checks and returns the actionable error list — an empty/malformed submission @@ -986,19 +901,6 @@ const suggestBoundaryTestsShape = { }; -const predictGateOutputSchema = { - predicted: z.boolean().optional(), - basis: z.string().optional(), - pack: z.enum(["gittensor", "oss-anti-slop"]).optional(), - conclusion: z.string().optional(), - title: z.string().optional(), - summary: z.string().optional(), - readinessScore: z.number().nullable().optional(), - blockers: z.unknown().optional(), - warnings: z.unknown().optional(), - funnel: z.unknown().optional(), - note: z.string().optional(), -}; const markNotificationsReadShape = { @@ -1019,20 +921,6 @@ const watchIssuesShape = { }; -// admin tool output schemas (#9518) now come from @loopover/contract/tools. -// #550: output schemas for the remaining tools (preflight/score/local-branch/agent), so MCP clients can -// machine-validate their results. Same lenient style as the schemas above — documented top-level keys, -// all optional, complex values as z.unknown(). No behavior change; these mirror the existing payloads. -const preflightResultOutputSchema = { - repoFullName: z.string().optional(), - generatedAt: z.string().optional(), - status: z.string().optional(), - lane: z.unknown().optional(), - reviewBurden: z.unknown().optional(), - linkedIssues: z.unknown().optional(), - findings: z.array(z.unknown()).optional(), - collisions: z.unknown().optional(), -}; const SIMULATE_OPEN_PR_PRESSURE_MAX_COUNT = 1_000_000; const simulateOpenPrPressureCountSchema = z.number().int().min(0).max(SIMULATE_OPEN_PR_PRESSURE_MAX_COUNT); diff --git a/src/queue/processors.ts b/src/queue/processors.ts index 618d4631b6..34e01414f4 100644 --- a/src/queue/processors.ts +++ b/src/queue/processors.ts @@ -172,8 +172,6 @@ import { parseLoopOverMentionCommand, sanitizePublicComment, } from "../github/commands"; -import { classifyPrCommandRequest } from "../github/pr-command-request"; -import { normalizeResolveFindingRef } from "../github/resolve-command"; import { ensurePullRequestLabel, removePullRequestLabel, @@ -338,7 +336,7 @@ import { import { isDuplicateClusterWinnerByClaim } from "../signals/duplicate-winner"; import { isDuplicateWinnerEnabledGlobally, resolveDuplicateWinnerEnabled } from "../settings/duplicate-winner-mode"; import { isOpenPrFileCollisionEnabledGlobally, resolveOpenPrFileCollisionEnabled } from "../settings/open-pr-file-collision-mode"; -import { buildAiReviewDiff, buildSecretScanDiff, buildUnifiedReviewDiff, totalAddedLineCount } from "../review/review-diff"; +import { buildAiReviewDiff, buildSecretScanDiff, totalAddedLineCount } from "../review/review-diff"; // #4013 step 4 (prep): buildAiReviewDiff/buildSecretScanDiff moved to review-diff.ts (a natural existing // home -- both already wrapped buildUnifiedReviewDiff there) rather than staying here, since keeping them // in this file would have made the new slop-detection.ts below circularly import this file just for @@ -372,7 +370,7 @@ import { startAiReviewLockHeartbeat } from "./ai-review-orchestration"; // loadOpenQueueCounts moved there too (it has no other callers besides generateSignalSnapshots and this // file's own buildBurdenForecasts) rather than staying here and importing back, which would have made the // two files circularly dependent. -import { generateSignalSnapshots, loadOpenQueueCounts } from "./signal-snapshot"; +import { loadOpenQueueCounts } from "./signal-snapshot"; export { generateSignalSnapshots } from "./signal-snapshot"; // #4013 step 3: same shim shape for the duplicate-cluster adjudication/reconciliation functions -- imported // here for this file's own internal callers, and re-exported so test/unit/duplicate-winner.test.ts and @@ -382,7 +380,6 @@ import { dupWinnerLinkedDuplicateCount, dupWinnerLinkedDuplicateWinnerNumber, linkedIssueDuplicatePullRequestRecordsForGate, - linkedIssueDuplicatePullRequestsForGate, reconcileLiveDuplicateSiblings, resolveScopedLinkedIssueClaimedAt, } from "./duplicate-detection"; @@ -437,7 +434,6 @@ import { // #4013 step 7: same shim shape for runRetentionPrune -- imported here for processJob's own internal call // below, and re-exported so test/unit/retention.test.ts and test/unit/selfhost-pg-retention.test.ts's // existing `import { ... } from "../../src/queue/processors"` keeps working unchanged. -import { runRetentionPrune } from "./retention"; import { runPrCommandPrologue, type PrCommandPrologueOutcome, type PrCommandPrologueSpec } from "./pr-command-prologue"; export { runRetentionPrune } from "./retention"; // #4013 step 8: same shim shape for the gate-check policy/publish/audit functions -- imported here for @@ -551,7 +547,7 @@ import { mapWithConcurrencyLimit, } from "../signals/focus-manifest-loader"; import { resolveRepositorySettings } from "../settings/repository-settings"; -import { getLastRepoDocRefreshAttemptedAtBulk, performRepoDocRefresh } from "../github/repo-doc-refresh-runner"; +import { getLastRepoDocRefreshAttemptedAtBulk, } from "../github/repo-doc-refresh-runner"; import { isRepoDocRefreshDue } from "../review/repo-doc-refresh-schedule"; import type { LocalBranchAnalysisInput } from "../signals/local-branch"; import { @@ -592,8 +588,7 @@ import { incompletePatchLessSecretScanFinding, markEligiblePatchLessFilesIncomplete, } from "./patchless-secret-scan"; -import { isRagEnabled } from "../review/rag-wire"; -import { computeImpactMap, type ImpactMapEntry } from "../review/impact-map"; +import { type ImpactMapEntry } from "../review/impact-map"; import { shouldComputeImpactMap } from "../review/impact-map-wire"; import { shouldEmitFixHandoff } from "../review/fix-handoff"; import { buildFixHandoffBlocks } from "../review/fix-handoff-render"; @@ -1871,7 +1866,7 @@ export async function sweepRepoBacklogConvergence( targetKey: repoFullName, outcome: "denied", detail: "agent actions paused — backlog-convergence sweep skipped", - metadata: { repoFullName, mode }, + metadata: { repoFullName, mode, requestedBy }, }); return; } @@ -1921,7 +1916,7 @@ export async function sweepRepoBacklogConvergence( targetKey: repoFullName, outcome: "denied", detail: `backlog-convergence sweep found ${orderedCandidates.length} open PR(s) needing convergence, all repair-exhausted`, - metadata: { repoFullName, examined: examinedCount, totalCandidates: orderedCandidates.length }, + metadata: { repoFullName, examined: examinedCount, totalCandidates: orderedCandidates.length, requestedBy }, }); } return; diff --git a/src/review/pr-reconciliation.ts b/src/review/pr-reconciliation.ts index a3c3eec9cc..d2050cc32c 100644 --- a/src/review/pr-reconciliation.ts +++ b/src/review/pr-reconciliation.ts @@ -12,7 +12,7 @@ import { githubRateLimitAdmissionKeyForToken } from "../github/client"; import { createInstallationToken } from "../github/app"; import { fetchLivePullRequest, reconcileOpenPullRequests } from "../github/backfill"; -import { getRepository, listRepositories, upsertPullRequestFromGitHub } from "../db/repositories"; +import { listRepositories, upsertPullRequestFromGitHub } from "../db/repositories"; import { isAgentConfigured } from "../settings/autonomy"; import { resolveRepositorySettings } from "../settings/repository-settings"; import { loadRepoFocusManifest } from "../signals/focus-manifest-loader"; diff --git a/src/review/rag-index.ts b/src/review/rag-index.ts index e363641782..69df3a881d 100644 --- a/src/review/rag-index.ts +++ b/src/review/rag-index.ts @@ -105,7 +105,7 @@ function ghHeaders(token: string | undefined, accept: string): Record { +async function fetchRepoTree(_env: Env, repoFullName: string, ref: string, token: string | undefined, admissionKey: GitHubRateLimitAdmissionKey | undefined): Promise { try { const { owner, name } = repoParts(repoFullName); const url = `https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/trees/${encodeURIComponent(ref)}?recursive=1`; @@ -169,7 +169,7 @@ async function readTextCapped(response: Response, maxBytes: number): Promise, ref: { ok: true; scope: "whole_pr" } | { ok: true; scope: "single"; findingCode: string }): { findings: AdvisoryFinding[]; reason?: "finding_not_found" } { if (ref.scope === "whole_pr") return { findings: [...warnings] }; const matches = warnings.filter((finding) => finding.code === ref.findingCode); if (matches.length === 0) return { findings: [], reason: "finding_not_found" }; return { findings: matches }; } /** Apply-to-findings wiring (#2181, apply slice of #1964). PURE — no DB I/O (the caller already resolved diff --git a/src/selfhost/pg-queue.ts b/src/selfhost/pg-queue.ts index e9ced3dc0b..8e3d373ac3 100644 --- a/src/selfhost/pg-queue.ts +++ b/src/selfhost/pg-queue.ts @@ -7,7 +7,6 @@ import type { DurableQueue } from "./backend-contracts"; import { logAudit, extractPayloadType, extractPayloadContext } from "./audit"; import { incr } from "./metrics"; import { withReviewSpan } from "./tracing"; -import { withOtelSpan } from "./otel"; import { capturePostHogError, withPostHogMonitor } from "./posthog"; import { ATTEMPT_FREE_RETRY_DEADLINE_MS, diff --git a/src/selfhost/sqlite-queue.ts b/src/selfhost/sqlite-queue.ts index 66dba5e92a..028be0f342 100644 --- a/src/selfhost/sqlite-queue.ts +++ b/src/selfhost/sqlite-queue.ts @@ -8,7 +8,6 @@ import type { DurableQueue } from "./backend-contracts"; import { logAudit, extractPayloadType, extractPayloadContext } from "./audit"; import { incr } from "./metrics"; import { withReviewSpan } from "./tracing"; -import { withOtelSpan } from "./otel"; import { capturePostHogError, withPostHogMonitor } from "./posthog"; import { ATTEMPT_FREE_RETRY_DEADLINE_MS, diff --git a/src/server.ts b/src/server.ts index 4524dead35..0243ab12b3 100644 --- a/src/server.ts +++ b/src/server.ts @@ -11,7 +11,6 @@ import { delimiter, join } from "node:path"; import { randomUUID } from "node:crypto"; import { DatabaseSync } from "node:sqlite"; import { serve, type Http2Bindings, type HttpBindings } from "@hono/node-server"; -import packageJson from "../package.json"; import worker from "./index"; import { githubRestRateLimitRemainingSamples } from "./github/client"; import { processJob } from "./queue/processors"; diff --git a/src/services/agent-orchestrator.ts b/src/services/agent-orchestrator.ts index 80783a70b8..a33b3c1ff8 100644 --- a/src/services/agent-orchestrator.ts +++ b/src/services/agent-orchestrator.ts @@ -22,7 +22,7 @@ import { import { contributorRepoStatsFromGittensor, fetchGittensorContributorSnapshot } from "../gittensor/api"; import { fetchPublicContributorProfile } from "../github/public"; import { getOrCreateScoringModelSnapshot } from "../scoring/model"; -import { loadContributorDecisionPackForServing, repoDecisionFromPack, type ActionPortfolio, type ActionPortfolioBucketName, type ContributorDecisionPack, type DecisionAction, type RepoDecision, type RepoOutcomeSummary } from "./decision-pack"; +import { loadContributorDecisionPackForServing, type ActionPortfolio, type ActionPortfolioBucketName, type ContributorDecisionPack, type DecisionAction, type RepoDecision, type RepoOutcomeSummary } from "./decision-pack"; import { loadOrComputeIssueQualityResponse } from "./issue-quality"; import { summarizeAgentBundleWithAi } from "./ai-summaries"; import { buildContributorFit, buildContributorOutcomeHistory, buildContributorProfile, buildContributorScoringProfile } from "../signals/engine"; diff --git a/src/services/decision-pack.ts b/src/services/decision-pack.ts index 7b95d9870b..a8d4183e9a 100644 --- a/src/services/decision-pack.ts +++ b/src/services/decision-pack.ts @@ -1340,7 +1340,7 @@ function portfolioScoreabilityImpact(decision: RepoDecision, bucket: ActionPortf return `Lane fit: ${decision.lane?.lane ?? "unknown"}; direct PR share ${decision.rewardUpside?.directPrShare ?? 0}.`; } -function portfolioMaintainerImpact(decision: RepoDecision, bucket: ActionPortfolioBucketName): string { +function portfolioMaintainerImpact(_decision: RepoDecision, bucket: ActionPortfolioBucketName): string { if (bucket === "cleanup") return "Cleanup lowers active-review pressure before adding more queue load."; if (bucket === "wait") return "Waiting on merge-ready or stale PR outcomes avoids noisy parallel work."; if (bucket === "maintainer_lane") return "Repo-owner work should improve intake quality and contributor routing."; diff --git a/src/signals/focus-manifest.ts b/src/signals/focus-manifest.ts index 51b1400dec..cb22c01317 100644 --- a/src/signals/focus-manifest.ts +++ b/src/signals/focus-manifest.ts @@ -124,7 +124,6 @@ import { type FocusManifestFinding, type FocusManifestGateConfig, type FocusManifestGuidance, - type FocusManifestSource, type MaxFindingsConfig, type PreMergeCheck, type ReviewFindingSeverity, diff --git a/test/integration/api.test.ts b/test/integration/api.test.ts index c7149b19e6..64538696a3 100644 --- a/test/integration/api.test.ts +++ b/test/integration/api.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import mcpPackageJson from "../../packages/loopover-mcp/package.json"; -import { createSessionForGitHubUser, hashToken } from "../../src/auth/security"; +import { createSessionForGitHubUser, } from "../../src/auth/security"; import { upsertBounty, upsertAgentCommandAnswer, diff --git a/test/unit/agent-orchestrator.test.ts b/test/unit/agent-orchestrator.test.ts index 106951dc62..8f6dc15fe0 100644 --- a/test/unit/agent-orchestrator.test.ts +++ b/test/unit/agent-orchestrator.test.ts @@ -9,7 +9,6 @@ import { preflightBranchWithAgent, preparePrPacketWithAgent, startAgentRun, - type AgentRunBundle, } from "../../src/services/agent-orchestrator"; import { buildAgentActionExplanationCard } from "../../src/services/agent-action-explanation-card"; import * as aiSummariesModule from "../../src/services/ai-summaries"; diff --git a/test/unit/ai-review.test.ts b/test/unit/ai-review.test.ts index 51d178b69e..22d6529a3b 100644 --- a/test/unit/ai-review.test.ts +++ b/test/unit/ai-review.test.ts @@ -5291,7 +5291,7 @@ describe("#8833: enforced boundaries between model judgment and deterministic fa }); it("#8833: whole-PR test-absence blockers demote ONLY when the path classifier contradicts them", async () => { - const { demoteTestEvidenceAbsenceBlockers, prHasTestPathEvidence } = await import("../../src/services/ai-review"); + const { demoteTestEvidenceAbsenceBlockers } = await import("../../src/services/ai-review"); const claims = ["No tests were added for this change", "The new helper is untested", "Null deref in src/a.ts"]; // Arm 1 — the PR really ships no test paths: the claim may well be TRUE, so it keeps its severity and the // zero-demotion path returns the SAME object (no reallocation). diff --git a/test/unit/backfill-2.test.ts b/test/unit/backfill-2.test.ts index 32fe1827cf..be5fb72baa 100644 --- a/test/unit/backfill-2.test.ts +++ b/test/unit/backfill-2.test.ts @@ -1,44 +1,12 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { - getInstallationHealth, - listCheckSummaries, - listContributorRepoStats, - listIssues, - listLatestRepoGithubTotalsSnapshots, listPullRequestFiles, - listPullRequestReviews, - listPullRequests, - listPullRequestDetailSyncStates, - listRecentMergedPullRequests, - upsertRecentMergedPullRequest, listLatestGitHubRateLimitObservations, - listRepoLabels, - listRepoSyncSegments, - listRepoSyncStates, - persistRepoGithubTotalsSnapshot, - recordGitHubRateLimitObservation, - upsertInstallation, - upsertInstallationHealth, - upsertRepoSyncSegment, - upsertRepoSyncState, - getPullRequest, - upsertPullRequestFile, upsertPullRequestFromGitHub, - upsertIssueFromGitHub, - upsertRepoLabel, - upsertRepositoryFromGitHub, - upsertRepositorySettings, } from "../../src/db/repositories"; import { - backfillOpenPullRequestDetails, - backfillRegisteredRepositories, - backfillRepositorySegment, - buildInstallationRepairDiagnostics, - enqueueRepositoryOpenDataBackfill, - enrichInstallationHealth, fetchAndStorePullRequestFilesForReview, fetchLinkedIssueFacts, - fetchLiveBaseBranchAdvancedAt, fetchLiveCiAggregate, fetchLiveReviewThreadBlockers, fetchLivePullRequestReviewDecision, @@ -49,13 +17,9 @@ import { isRateLimitedGitHubFailure, mergeRequiredCiContexts, reconcileOpenPullRequests, - refreshContributorActivity, - refreshInstallationHealth, - refreshPullRequestDetails, } from "../../src/github/backfill"; import { clearGitHubResponseCacheForTest, - githubRateLimitAdmissionKeyForInstallation, githubRateLimitAdmissionKeyForPublicToken, setGitHubResponseCache, type CachedGitHubResponse, @@ -65,7 +29,6 @@ import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; -import { generatePrivateKeyPem } from "../helpers/github-app-key"; // #4682 incident (2026-07-10): the stored-body cap used to be 4000 chars -- well under what a compliant // screenshot-evidence table (or any sufficiently detailed PR/issue) actually needs -- and every body-content @@ -92,46 +55,7 @@ async function seedRegisteredRepo(env: Env) { ); } -async function persistTotalsSnapshot( - env: Env, - overrides: { - fetchedAt?: string; - sourceKind?: "github" | "installation"; - openIssuesTotal?: number; - openPullRequestsTotal?: number; - mergedPullRequestsTotal?: number; - closedUnmergedPullRequestsTotal?: number; - labelsTotal?: number; - } = {}, -) { - await persistRepoGithubTotalsSnapshot(env, { - id: crypto.randomUUID(), - repoFullName: "JSONbored/gittensory", - openIssuesTotal: overrides.openIssuesTotal ?? 0, - openPullRequestsTotal: overrides.openPullRequestsTotal ?? 0, - mergedPullRequestsTotal: overrides.mergedPullRequestsTotal ?? 0, - closedUnmergedPullRequestsTotal: overrides.closedUnmergedPullRequestsTotal ?? 0, - labelsTotal: overrides.labelsTotal ?? 0, - sourceKind: overrides.sourceKind ?? "github", - fetchedAt: overrides.fetchedAt ?? "2026-05-25T00:00:00.000Z", - payload: {}, - }); -} -function githubTotalsResponse(counts: { openIssues: number; openPullRequests: number; mergedPullRequests: number; closedPullRequests: number; labels: number }) { - return Response.json({ - data: { - rateLimit: { remaining: 4999, resetAt: "2026-05-25T01:00:00.000Z" }, - repository: { - issues: { totalCount: counts.openIssues }, - openPullRequests: { totalCount: counts.openPullRequests }, - mergedPullRequests: { totalCount: counts.mergedPullRequests }, - closedPullRequests: { totalCount: counts.closedPullRequests }, - labels: { totalCount: counts.labels }, - }, - }, - }); -} describe("GitHub backfill", () => { afterEach(() => { diff --git a/test/unit/backfill.test.ts b/test/unit/backfill.test.ts index a524c66ad0..4fc195415d 100644 --- a/test/unit/backfill.test.ts +++ b/test/unit/backfill.test.ts @@ -38,19 +38,9 @@ import { buildInstallationRepairDiagnostics, enqueueRepositoryOpenDataBackfill, enrichInstallationHealth, - fetchAndStorePullRequestFilesForReview, fetchBaseAheadBy, fetchLinkedIssueClosedByPullRequest, - fetchLinkedIssueFacts, fetchLiveBaseBranchAdvancedAt, - fetchLiveCiAggregate, - fetchLiveReviewThreadBlockers, - fetchNamedCheckRunConclusion, - fetchRequiredStatusContexts, - isOwnReviewThreadAuthor, - isRateLimitedGitHubFailure, - mergeRequiredCiContexts, - reconcileOpenPullRequests, refreshContributorActivity, refreshInstallationHealth, refreshPullRequestDetails, @@ -64,7 +54,7 @@ import { } from "../../src/github/client"; import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; -import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; +import { renderMetrics, } from "../../src/selfhost/metrics"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; diff --git a/test/unit/content-lane-netuid-verification.test.ts b/test/unit/content-lane-netuid-verification.test.ts index c3ebae0462..cc65db2b7e 100644 --- a/test/unit/content-lane-netuid-verification.test.ts +++ b/test/unit/content-lane-netuid-verification.test.ts @@ -83,7 +83,7 @@ describe("fetchTaostatsSubnetIdentity (key-gated, fail-open)", () => { it("sends the key as a RAW Authorization header (not Bearer)", async () => { let auth: string | null = null; - const f = (async (input: RequestInfo | URL, init?: RequestInit) => { + const f = (async (_input: RequestInfo | URL, init?: RequestInit) => { auth = new Headers(init?.headers).get("authorization"); return new Response(JSON.stringify({ data: [{ netuid: 9, subnet_name: "N" }] }), { status: 200 }); }) as unknown as typeof fetch; diff --git a/test/unit/content-lane-source-evidence.test.ts b/test/unit/content-lane-source-evidence.test.ts index 5738706730..05305d91cf 100644 --- a/test/unit/content-lane-source-evidence.test.ts +++ b/test/unit/content-lane-source-evidence.test.ts @@ -740,7 +740,7 @@ describe("checkOneSourceUrl branches", () => { it("returns immediately from a passing HEAD (no GET) — HEAD `passed` early return", async () => { // HEAD returns 200 → checkOneSourceUrl returns head without ever issuing a GET. let getCalls = 0; - const fetchImpl = (async (input: RequestInfo | URL, init?: RequestInit) => { + const fetchImpl = (async (_input: RequestInfo | URL, init?: RequestInit) => { const method = ((init?.method as string) || "GET").toUpperCase(); if (method === "GET") getCalls += 1; return new Response("ok", { status: 200 }); diff --git a/test/unit/discovery-index/upload-sourcemaps.test.ts b/test/unit/discovery-index/upload-sourcemaps.test.ts index 1ce6a07182..3781922672 100644 --- a/test/unit/discovery-index/upload-sourcemaps.test.ts +++ b/test/unit/discovery-index/upload-sourcemaps.test.ts @@ -270,7 +270,7 @@ describe("discovery-index upload-sourcemaps -- PostHog (#8289)", () => { it("retries release validation until it succeeds, logging a retry warning each time", async () => { let validateAttempts = 0; - spawnSyncMock.mockImplementation((command: string, args: string[]) => { + spawnSyncMock.mockImplementation((_command: string, args: string[]) => { if (isPostHogValidateReleaseCall(args)) { validateAttempts += 1; return validateAttempts < 3 ? { status: 1, stdout: "", stderr: "release not fully propagated yet" } : { status: 0, stdout: "release visible" }; @@ -287,7 +287,7 @@ describe("discovery-index upload-sourcemaps -- PostHog (#8289)", () => { it("falls back to the default attempt count when DISCOVERY_INDEX_POSTHOG_VALIDATE_ATTEMPTS is invalid", async () => { let validateAttempts = 0; - spawnSyncMock.mockImplementation((command: string, args: string[]) => { + spawnSyncMock.mockImplementation((_command: string, args: string[]) => { if (isPostHogValidateReleaseCall(args)) { validateAttempts += 1; return { status: 1, stdout: "", stderr: "still not visible" }; @@ -303,7 +303,7 @@ describe("discovery-index upload-sourcemaps -- PostHog (#8289)", () => { it("clamps an oversized DISCOVERY_INDEX_POSTHOG_VALIDATE_ATTEMPTS to its max of 20", async () => { let validateAttempts = 0; - spawnSyncMock.mockImplementation((command: string, args: string[]) => { + spawnSyncMock.mockImplementation((_command: string, args: string[]) => { if (isPostHogValidateReleaseCall(args)) { validateAttempts += 1; return { status: 1, stdout: "", stderr: "still not visible" }; @@ -317,7 +317,7 @@ describe("discovery-index upload-sourcemaps -- PostHog (#8289)", () => { it("tolerates a validate-release result missing stdout/stderr, and waits between retries", async () => { let attempt = 0; - spawnSyncMock.mockImplementation((command: string, args: string[]) => { + spawnSyncMock.mockImplementation((_command: string, args: string[]) => { if (!isPostHogValidateReleaseCall(args)) return spawnSuccess(); attempt += 1; if (attempt === 1) return { status: 1 }; @@ -330,7 +330,7 @@ describe("discovery-index upload-sourcemaps -- PostHog (#8289)", () => { }); it("exhausts validation attempts and fails softly (exit 0) when not strict", async () => { - spawnSyncMock.mockImplementation((command: string, args: string[]) => { + spawnSyncMock.mockImplementation((_command: string, args: string[]) => { if (isPostHogValidateReleaseCall(args)) return { status: 1, stdout: "", stderr: "still not visible" }; return spawnSuccess(); }); @@ -341,7 +341,7 @@ describe("discovery-index upload-sourcemaps -- PostHog (#8289)", () => { }); it("exhausts validation attempts and fails strictly (exit 1) when set to strict", async () => { - spawnSyncMock.mockImplementation((command: string, args: string[]) => { + spawnSyncMock.mockImplementation((_command: string, args: string[]) => { if (isPostHogValidateReleaseCall(args)) return { status: 1, stdout: "", stderr: "still not visible" }; return spawnSuccess(); }); diff --git a/test/unit/federated-bundle.test.ts b/test/unit/federated-bundle.test.ts index b1f2543b04..6ac44d230a 100644 --- a/test/unit/federated-bundle.test.ts +++ b/test/unit/federated-bundle.test.ts @@ -300,8 +300,8 @@ describe("buildFederatedBundle() — fail-safe", () => { const db = makeDb(); const secret = await getOrCreateAnonSecret(db); const noRowsDb = { - prepare: (sql: string) => ({ - bind: (...args: unknown[]) => ({ + prepare: (_sql: string) => ({ + bind: (..._args: unknown[]) => ({ first: async () => ({ value: secret }), all: async () => ({ results: undefined }), run: async () => ({}), diff --git a/test/unit/focus-manifest-loader.test.ts b/test/unit/focus-manifest-loader.test.ts index 69cdd4cead..a636a1a149 100644 --- a/test/unit/focus-manifest-loader.test.ts +++ b/test/unit/focus-manifest-loader.test.ts @@ -3,7 +3,6 @@ import { createTestEnv } from "../helpers/d1"; import type { JsonValue } from "../../src/types"; import { fetchRepoFocusManifestFile, - hasLocalManifest, loadPublicRepoFocusManifest, loadRepoFocusManifest, loadRepoFocusManifests, diff --git a/test/unit/governor-write-rate-limit.test.ts b/test/unit/governor-write-rate-limit.test.ts index d53ed9883b..264186f298 100644 --- a/test/unit/governor-write-rate-limit.test.ts +++ b/test/unit/governor-write-rate-limit.test.ts @@ -21,7 +21,7 @@ const tightPolicies: WriteRateLimitPolicies = { backoffBaseMs: 100, }; -function emptyState(nowMs: number): { +function emptyState(_nowMs: number): { buckets: WriteRateLimitBucketStore; backoffAttempts: WriteRateLimitBackoffStore; } { diff --git a/test/unit/knob-loosening-run.test.ts b/test/unit/knob-loosening-run.test.ts index 8162665712..3773f96aaa 100644 --- a/test/unit/knob-loosening-run.test.ts +++ b/test/unit/knob-loosening-run.test.ts @@ -1,7 +1,7 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { splitBacktestCorpus } from "@loopover/engine"; import * as looseningKnobs from "../../src/services/loosening-knobs"; -import { LOOSENABLE_KNOBS, type LoosenableKnob } from "../../src/services/loosening-knobs"; +import { LOOSENABLE_KNOBS, } from "../../src/services/loosening-knobs"; import { GENERIC_LIVE_KNOBS, genericLiveKnobs, diff --git a/test/unit/linked-issue-label-propagation-fetch.test.ts b/test/unit/linked-issue-label-propagation-fetch.test.ts index ebde5aaf1f..d9f144f958 100644 --- a/test/unit/linked-issue-label-propagation-fetch.test.ts +++ b/test/unit/linked-issue-label-propagation-fetch.test.ts @@ -22,16 +22,6 @@ async function publishAddressedSatisfactionVerdict(env: Env, repoFullName: strin }); } -// `getRepositoryCollaboratorPermission` mints its own installation token internally with no fallback to -// the public token, so a maintainer-authored-issue test that reaches it (i.e. isn't already short-circuited -// by a literal-owner or ADMIN_GITHUB_LOGINS match) needs a real signable key or the mint throws before ever -// reaching the stubbed collaborators endpoint -- mirrors the same helper duplicated across other test files -// (e.g. `test/unit/queue.test.ts`, `test/unit/github-app.test.ts`). -// Split so the literal PEM marker text never appears contiguous in source -- the review-safety secrets -// scanner's private_key_block pattern is a pure text match with no awareness that the bytes between these -// markers are freshly generated per test run, not a real credential (src/review/safety.ts). -const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" "); -const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" "); // #regression-safe-propagation: `fetchLinkedIssueLabelsForPropagation` returns `{labels, inconclusive}`, not a // bare `string[]` -- `inconclusive` defaults false (a confirmed result) in every assertion below except the diff --git a/test/unit/linked-issue-satisfaction-run.test.ts b/test/unit/linked-issue-satisfaction-run.test.ts index 22079a8ae2..fd38e2e9de 100644 --- a/test/unit/linked-issue-satisfaction-run.test.ts +++ b/test/unit/linked-issue-satisfaction-run.test.ts @@ -23,12 +23,6 @@ import type { Advisory, PullRequestFileRecord, RepositorySettings } from "../../ import { createTestEnv } from "../helpers/d1"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; -// Split so the literal PEM marker text never appears contiguous in source -- the review-safety secrets -// scanner's private_key_block pattern is a pure text match with no awareness that the bytes between these -// markers are freshly generated per test run, not a real credential (src/review/safety.ts). Mirrors the -// identical helper duplicated across other test files (e.g. test/unit/queue.test.ts). -const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" "); -const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" "); function satisfactionJson(over: Partial<{ status: string; rationale: string; confidence: number }> = {}): string { return JSON.stringify({ diff --git a/test/unit/lint-composite-actions-script.test.ts b/test/unit/lint-composite-actions-script.test.ts index 8d0c464ff5..2a258a4a6f 100644 --- a/test/unit/lint-composite-actions-script.test.ts +++ b/test/unit/lint-composite-actions-script.test.ts @@ -111,7 +111,7 @@ describe("runLint (#7459)", () => { const code = runLint({ actionsDir: ".github/actions", readdir: () => [dir("bad")], - readFile: (path: string, encoding?: string) => { + readFile: (_path: string, encoding?: string) => { if (encoding === "utf8") return content; return "exists"; }, @@ -127,7 +127,7 @@ describe("runLint (#7459)", () => { const code = runLint({ actionsDir: ".github/actions", readdir: () => [dir("ok")], - readFile: (path: string, encoding?: string) => (encoding === "utf8" ? WELL_FORMED : "exists"), + readFile: (_path: string, encoding?: string) => (encoding === "utf8" ? WELL_FORMED : "exists"), validateSchema, log: () => {}, error: () => {}, diff --git a/test/unit/maintainer-recap-wire.test.ts b/test/unit/maintainer-recap-wire.test.ts index f13ce95792..069dbf372e 100644 --- a/test/unit/maintainer-recap-wire.test.ts +++ b/test/unit/maintainer-recap-wire.test.ts @@ -244,7 +244,7 @@ describe("runMaintainerRecapJob — cross-repo digest (#1963, #2248)", () => { await recordGateBlockOutcome(env, { repoFullName: "owner/alpha", pullNumber: 1, blockerCodes: ["slop_risk"] }); await upsertPullRequestFromGitHub(env, "owner/alpha", { number: 2, title: "human PR", state: "closed", user: { login: "human-bob" } }); await recordGateBlockOutcome(env, { repoFullName: "owner/alpha", pullNumber: 2, blockerCodes: ["slop_risk"] }); - vi.stubGlobal("fetch", async (url: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (url: RequestInfo | URL, _init?: RequestInit) => { if (String(url) === HOOK) return new Response(null, { status: 204 }); if (String(url) === "https://api.gittensor.io/miners") return Response.json([{ uid: 1, githubUsername: "miner-alice", githubId: "1" }]); return new Response(null, { status: 204 }); diff --git a/test/unit/maintainer-recap.test.ts b/test/unit/maintainer-recap.test.ts index d5da819ba9..7e41672cf4 100644 --- a/test/unit/maintainer-recap.test.ts +++ b/test/unit/maintainer-recap.test.ts @@ -364,7 +364,7 @@ describe("runMaintainerRecap (#2252 end-to-end orchestration)", () => { }); it("still delivers to Slack when Discord fetch fails (Discord outage must not abort Slack)", async () => { - vi.stubGlobal("fetch", async (url: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (url: RequestInfo | URL, _init?: RequestInit) => { if (String(url) === DISCORD_HOOK) throw new Error("discord down"); if (String(url) === SLACK_HOOK) return new Response(null, { status: 204 }); return new Response(null, { status: 204 }); diff --git a/test/unit/mcp-cli-validate-config.test.ts b/test/unit/mcp-cli-validate-config.test.ts index d55009a99b..af463836c8 100644 --- a/test/unit/mcp-cli-validate-config.test.ts +++ b/test/unit/mcp-cli-validate-config.test.ts @@ -1,4 +1,4 @@ -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; diff --git a/test/unit/miner-ams-eligibility-backtest.test.ts b/test/unit/miner-ams-eligibility-backtest.test.ts index 4e2439547f..facbd96d63 100644 --- a/test/unit/miner-ams-eligibility-backtest.test.ts +++ b/test/unit/miner-ams-eligibility-backtest.test.ts @@ -1,4 +1,4 @@ -import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { mkdtempSync, rmSync} from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; diff --git a/test/unit/miner-attempt-cli.test.ts b/test/unit/miner-attempt-cli.test.ts index 68b0cb2333..56ca1989c5 100644 --- a/test/unit/miner-attempt-cli.test.ts +++ b/test/unit/miner-attempt-cli.test.ts @@ -1385,7 +1385,6 @@ describe("runAttempt (#5132)", () => { it("#8543: records NOTHING when the coding-task-spec is ready (capture is scoped to the infeasible branch)", async () => { const { allocator, claimLedger, eventLedger, attemptLog, governorLedger } = tempLedgers(); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); const { store, fired } = fakeSignalStore(); const worktreeResult = fakeWorktreeResult(); const runMinerAttemptSpy = vi.fn().mockResolvedValue({ diff --git a/test/unit/miner-ci-poller.test.ts b/test/unit/miner-ci-poller.test.ts index 545b906c3a..de2bfc3f4b 100644 --- a/test/unit/miner-ci-poller.test.ts +++ b/test/unit/miner-ci-poller.test.ts @@ -29,7 +29,7 @@ function checksResponse(checks: unknown[], init: ResponseInit & { totalCount?: n describe("miner CI check-run poller (#2323)", () => { it("fetches PR head SHA and check runs with read-only authenticated GET requests", async () => { - const fetchFn = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + const fetchFn = vi.fn(async (input: RequestInfo | URL, _init?: RequestInit) => { const url = String(input); if (url.endsWith("/repos/acme/widgets/pulls/42")) return prResponse("head-sha"); if (url.endsWith("/repos/acme/widgets/commits/head-sha/check-runs?per_page=100&page=1")) { diff --git a/test/unit/miner-discover-cli-eligibility-metadata.test.ts b/test/unit/miner-discover-cli-eligibility-metadata.test.ts index 71c5ebd2b2..c414a7b3da 100644 --- a/test/unit/miner-discover-cli-eligibility-metadata.test.ts +++ b/test/unit/miner-discover-cli-eligibility-metadata.test.ts @@ -270,7 +270,6 @@ describe("recordEligibilityExclusionSignals via runDiscover (#8544)", () => { ]; const { opts } = discoverWith(issues, new Map([["acme/widgets", trustworthyProfile]]), { nowMs: NOW }); const { fired, store } = fakeSignalStore(); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); const exitCode = await runDiscover(["acme/widgets", "--json"], { ...opts, initSignalTrackingStore: () => store }); expect(exitCode).toBe(0); expect(fired).toEqual([ @@ -298,7 +297,6 @@ describe("recordEligibilityExclusionSignals via runDiscover (#8544)", () => { ]; const { opts } = discoverWith(issues, new Map([["acme/widgets", trustworthyProfile]]), { nowMs: NOW }); const { fired, store } = fakeSignalStore(); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); await runDiscover(["acme/widgets", "--json"], { ...opts, initSignalTrackingStore: () => store }); expect(fired).toEqual([ { @@ -313,7 +311,6 @@ describe("recordEligibilityExclusionSignals via runDiscover (#8544)", () => { const issues = [fanOutIssue({ issueNumber: 1, labels: ["help wanted"] })]; const { opts } = discoverWith(issues, new Map([["acme/widgets", trustworthyProfile]]), { nowMs: NOW }); const { fired, store } = fakeSignalStore(); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); await runDiscover(["acme/widgets", "--json"], { ...opts, initSignalTrackingStore: () => store }); expect(fired).toEqual([]); expect(store.recordRuleFired).not.toHaveBeenCalled(); @@ -349,7 +346,6 @@ describe("recordEligibilityExclusionSignals via runDiscover (#8544)", () => { calls += 1; if (calls === 1) throw new Error("write failed"); }); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); const exitCode = await runDiscover(["acme/widgets", "--json"], { ...opts, initSignalTrackingStore: () => ({ @@ -366,7 +362,6 @@ describe("recordEligibilityExclusionSignals via runDiscover (#8544)", () => { const issues = [fanOutIssue({ issueNumber: 2, labels: ["blocked"] })]; const { opts } = discoverWith(issues, new Map([["acme/widgets", trustworthyProfile]])); const { store } = fakeSignalStore(); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); vi.spyOn(Date, "now").mockReturnValue(NOW); const exitCode = await runDiscover(["acme/widgets", "--json"], { ...opts, initSignalTrackingStore: () => store }); expect(exitCode).toBe(0); diff --git a/test/unit/miner-discover-cli.test.ts b/test/unit/miner-discover-cli.test.ts index b8fb6791dd..734b9c8544 100644 --- a/test/unit/miner-discover-cli.test.ts +++ b/test/unit/miner-discover-cli.test.ts @@ -16,7 +16,7 @@ import { runDiscover, sanitizeDiscoverDisplayText, } from "../../packages/loopover-miner/lib/discover-cli"; -import { bin, runCapture } from "./support/miner-cli-harness"; +import { runCapture } from "./support/miner-cli-harness"; const NOW = Date.parse("2026-07-09T12:00:00.000Z"); @@ -575,7 +575,7 @@ describe("runDiscover (#4247)", () => { const initPolicyVerdictCache = vi.fn(); const initRankedCandidatesStore = vi.fn(); const fetchCandidateIssuesWithSummary = vi.fn( - async (targets, token, fanOutOptions) => { + async (_targets, _token, fanOutOptions) => { expect(fanOutOptions).toMatchObject({ policyDocCache: null, policyVerdictCache: null, @@ -1665,7 +1665,6 @@ describe("runDiscover onResult hook (#6522)", () => { ]; const { opts } = discoverWith(issues, new Map([["acme/widgets", trustworthyProfile]])); const { fired, store } = fakeSignalStore(); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); const exitCode = await runDiscover(["acme/widgets", "--json"], { ...opts, initSignalTrackingStore: () => store }); expect(exitCode).toBe(0); expect(fired).toEqual([ @@ -1678,7 +1677,6 @@ describe("runDiscover onResult hook (#6522)", () => { const issues = [fanOutIssue({ issueNumber: 1, labels: ["help wanted"] })]; const { opts } = discoverWith(issues, new Map([["acme/widgets", trustworthyProfile]])); const { fired, store } = fakeSignalStore(); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); await runDiscover(["acme/widgets", "--json"], { ...opts, initSignalTrackingStore: () => store }); expect(fired).toEqual([]); expect(store.recordRuleFired).not.toHaveBeenCalled(); @@ -1730,7 +1728,6 @@ describe("runDiscover onResult hook (#6522)", () => { calls += 1; if (calls === 1) throw new Error("write failed"); }); - const log = vi.spyOn(console, "log").mockImplementation(() => undefined); const exitCode = await runDiscover(["acme/widgets", "--json"], { ...opts, initSignalTrackingStore: () => ({ diff --git a/test/unit/miner-metrics-cli.test.ts b/test/unit/miner-metrics-cli.test.ts index 2bf93e97c8..cf8defcc2b 100644 --- a/test/unit/miner-metrics-cli.test.ts +++ b/test/unit/miner-metrics-cli.test.ts @@ -35,11 +35,6 @@ function tempEventLedger() { return ledger; } -function tempDbPath() { - const root = mkdtempSync(join(tmpdir(), "loopover-miner-metrics-cli-")); - roots.push(root); - return join(root, "prediction-ledger.sqlite3"); -} function appendPrediction(ledger: PredictionLedger, targetId: number, conclusion: string) { ledger.appendPrediction({ repoFullName: REPO, targetId, conclusion, pack: "gittensor", engineVersion: "0.2.0" }); diff --git a/test/unit/openapi.test.ts b/test/unit/openapi.test.ts index e3632cb783..2ba16a5d31 100644 --- a/test/unit/openapi.test.ts +++ b/test/unit/openapi.test.ts @@ -1,14 +1,12 @@ import { describe, expect, it } from "vitest"; import { buildOpenApiSpec } from "../../src/openapi/spec"; -import { - gatePrecisionOutputSchema, - maintainerMeasurementReportOutputSchema, -} from "../../src/mcp/server"; // #9518: these tools' output schemas moved to @loopover/contract as each category migrated. The // REST<->MCP parity guards below are unchanged in intent -- they now read the contract (the single // source both the MCP server and these assertions derive from) instead of server-local declarations // that no longer exist. import { + GetGatePrecisionOutput, + GetOutcomeCalibrationOutput, GetMaintainerNoiseOutput, GetAmsMinerCohortOutput, GetActivationPreviewOutput, @@ -478,12 +476,17 @@ describe("OpenAPI contract", () => { { path: "/v1/repos/{owner}/{repo}/gate-precision", response: "GatePrecisionResponse", - outputShape: gatePrecisionOutputSchema, + // #9302 guard, re-anchored: this asserted against src/mcp/server.ts's own gatePrecisionOutputSchema, + // which the tool stopped registering when #9518 moved its output to the contract. The two shapes were + // still identical, so nothing had drifted YET -- but the guard was watching an object no runtime reads, + // so a future contract change would have sailed past it. Now it reads what the tool actually registers. + outputShape: GetGatePrecisionOutput.shape, }, { path: "/v1/repos/{owner}/{repo}/outcome-calibration", response: "OutcomeCalibrationResponse", - outputShape: maintainerMeasurementReportOutputSchema, + // Same re-anchoring as gate-precision directly above. + outputShape: GetOutcomeCalibrationOutput.shape, }, { path: "/v1/repos/{owner}/{repo}/activation-preview", diff --git a/test/unit/opportunity-metadata-signals.test.ts b/test/unit/opportunity-metadata-signals.test.ts index 8fae843264..9a1975941a 100644 --- a/test/unit/opportunity-metadata-signals.test.ts +++ b/test/unit/opportunity-metadata-signals.test.ts @@ -4,7 +4,6 @@ import { computeMetadataDupRisk, computeMetadataFeasibility, computeMetadataPotential, - opportunityMetadataInternals, rankMetadataOpportunities, } from "../../packages/loopover-engine/src/opportunity-metadata"; import { pickTopMetadataOpportunities } from "../../packages/loopover-engine/src/metadata-top-pick"; diff --git a/test/unit/ops-wire.test.ts b/test/unit/ops-wire.test.ts index 020e65c0a4..3be4643dfa 100644 --- a/test/unit/ops-wire.test.ts +++ b/test/unit/ops-wire.test.ts @@ -461,7 +461,6 @@ describe("runOpsAlerts — cron path over gittensory's outcome data", () => { outcome: "completed", }); } - const errors = vi.spyOn(console, "error").mockImplementation(() => {}); const found = await runOpsAlerts(env); @@ -488,7 +487,6 @@ describe("runOpsAlerts — cron path over gittensory's outcome data", () => { metadata: { repoFullName: "owner/repo", pullNumber: 99, inconclusive: true }, }); } - const errors = vi.spyOn(console, "error").mockImplementation(() => {}); const found = await runOpsAlerts(env); diff --git a/test/unit/orb-analytics.test.ts b/test/unit/orb-analytics.test.ts index cce3222701..17e93b2e50 100644 --- a/test/unit/orb-analytics.test.ts +++ b/test/unit/orb-analytics.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; import { computeFleetAnalytics, getFleetHealthSummary, HEALTH_STALE_HOURS, wilsonInterval } from "../../src/orb/analytics"; -import { createTestEnv, TestD1Database } from "../helpers/d1"; +import { createTestEnv, } from "../helpers/d1"; let seq = 0; /** Insert N orb_signals rows for one instance with a fixed verdict/outcome/reversal/cycle. */ diff --git a/test/unit/parity-wire.test.ts b/test/unit/parity-wire.test.ts index 43f733d66c..fb361a25f7 100644 --- a/test/unit/parity-wire.test.ts +++ b/test/unit/parity-wire.test.ts @@ -433,7 +433,7 @@ async function seedGateEnabledRepo(env: Env): Promise { // every finalize-path test needs the live PR to actually resolve, matching prWebhook's own head sha (#gate123) // so freshness classifies as "current" rather than "unavailable"/"head_changed". function stubFinalizeFetch(confirmedAuthor: string | null): void { - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); if (url === "https://api.gittensor.io/miners") return Response.json(confirmedAuthor ? [{ uid: 7, githubUsername: confirmedAuthor, githubId: "123", totalPrs: 4, totalMergedPrs: 3, totalOpenPrs: 1, totalClosedPrs: 0, totalOpenIssues: 0, totalClosedIssues: 0, totalSolvedIssues: 0, totalValidSolvedIssues: 0, isEligible: true, credibility: 1, eligibleRepoCount: 1 }] : []); if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" }); diff --git a/test/unit/patchless-secret-scan.test.ts b/test/unit/patchless-secret-scan.test.ts index 21b93f2fb2..39e6ee770a 100644 --- a/test/unit/patchless-secret-scan.test.ts +++ b/test/unit/patchless-secret-scan.test.ts @@ -6,7 +6,6 @@ import { incompletePatchLessSecretScanFinding, SECRET_SCAN_PATCH_FALLBACK_MAX_CHARS, SECRET_SCAN_PATCH_FALLBACK_MAX_FETCHES, - markEligiblePatchLessFilesIncomplete, patchlessSecretScanInternals, } from "../../src/queue/patchless-secret-scan"; import type { FileFetcher } from "../../src/review/review-grounding"; diff --git a/test/unit/pr-labeled-public-surface.test.ts b/test/unit/pr-labeled-public-surface.test.ts index 5ec19c5b6d..8214ee2e0c 100644 --- a/test/unit/pr-labeled-public-surface.test.ts +++ b/test/unit/pr-labeled-public-surface.test.ts @@ -31,7 +31,7 @@ describe("a label change runs the public-surface pipeline immediately (#9059)", await upsertPullRequestDetailSyncState(env, { repoFullName: `owner/${repo}`, pullNumber: number, status: "complete", headSha: head, filesSyncedAt: "2020-01-01T00:00:00.000Z", reviewsSyncedAt: "2020-01-01T00:00:00.000Z", checksSyncedAt: "2020-01-01T00:00:00.000Z", lastSyncedAt: "2020-01-01T00:00:00.000Z" }); } - function stubGitHub(repo: string, number: number, head: string): void { + function stubGitHub(_repo: string, number: number, head: string): void { vi.stubGlobal("fetch", async (input: RequestInfo | URL) => { const url = input.toString(); if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" }); diff --git a/test/unit/predicted-gate-engine.test.ts b/test/unit/predicted-gate-engine.test.ts index d037bd7069..4e225bdf16 100644 --- a/test/unit/predicted-gate-engine.test.ts +++ b/test/unit/predicted-gate-engine.test.ts @@ -1853,10 +1853,6 @@ describe("predicted-gate engine branch coverage (#2283)", () => { ); expect(recentMergedNoLinks.clusters.length).toBeGreaterThan(0); - const selfAuthoredPathOverlap = buildCollisionReport(BRANCH_REPO.fullName, [], [ - { ...pr(BRANCH_REPO.fullName, 14, "qwerty alpha"), authorLogin: "alice", changedFiles: ["src/services/upload/retry.ts"] }, - { ...pr(BRANCH_REPO.fullName, 15, "asdf beta"), authorLogin: "alice", changedFiles: ["src/services/upload/retry.ts"] }, - ]); const differentLinkedIssues = buildCollisionReport(BRANCH_REPO.fullName, [], [ { ...pr(BRANCH_REPO.fullName, 16, "upload retry client handler"), authorLogin: "alice", linkedIssues: [1], changedFiles: ["src/core/upload.ts"] }, { ...pr(BRANCH_REPO.fullName, 17, "upload retry service handler"), authorLogin: "bob", linkedIssues: [2], changedFiles: ["src/core/upload.ts"] }, diff --git a/test/unit/queue-2.test.ts b/test/unit/queue-2.test.ts index 73a4e7d1a9..1ef9edfe3f 100644 --- a/test/unit/queue-2.test.ts +++ b/test/unit/queue-2.test.ts @@ -1,71 +1,37 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { generateKeyPairSync } from "node:crypto"; +import { } from "node:crypto"; import { clearInstallationTokenCacheForTest } from "../../src/github/app"; import { clearReviewSuppressionCacheForTest } from "../../src/review/review-memory-wire"; import { PR_PANEL_COMMENT_MARKER } from "../../src/github/comments"; import * as backfillModule from "../../src/github/backfill"; -import * as rateLimitModule from "../../src/github/rate-limit"; import * as repositoriesModule from "../../src/db/repositories"; import * as decisionRecordModule from "../../src/review/decision-record"; -import * as reviewEffortModule from "../../src/review/review-effort"; -import * as repositorySettingsModule from "../../src/settings/repository-settings"; import * as posthogModule from "../../src/selfhost/posthog"; import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; -import { jobCoalesceKey } from "../../src/selfhost/queue-common"; +import { } from "../../src/selfhost/queue-common"; import { - listCollisionEdges, - createAgentRun, - getCommandUsefulnessSummary, - getBurdenForecast, - getContributorEvidence, - getAgentRun, - getContributorScoringProfile, - getWebhookEvent, getInstallation, - getLatestUpstreamRulesetSnapshot, getPullRequest, - getPullRequestDetailSyncState, - upsertPullRequestDetailSyncState, getRepository, - listUpstreamDriftReports, listInstallationHealth, - listProductUsageDailyRollups, listProductUsageEvents, - listPullRequests, listPullRequestFiles, listRepoSyncStates, - listSignalSnapshots, - persistSignalSnapshot, - recordGateBlockOutcome, - markGateOutcomeOverridden, - recordProductUsageEvent, - upsertAgentCommandAnswer, upsertCheckSummary, - upsertIssueFromGitHub, upsertRepoSyncSegment, upsertInstallation, - updatePullRequestSlopAssessment, upsertOfficialMinerDetection, upsertPullRequestFile, upsertPullRequestFromGitHub, - upsertIssueWatchSubscription, - upsertRepositoryAiKey, upsertRepositorySettings, upsertRepositoryFromGitHub, putCachedAiReview, - markAiReviewPublished, - putCachedAiSlopAdvisory, - putCachedLinkedIssueSatisfaction, - recordReviewSuppression, - listReviewSuppressions, - setGlobalAgentFrozen, } from "../../src/db/repositories"; -import { agentMaintenanceHeadMatchesGate, changedPathsForGuardrail, claimAiReviewLock, claimPrActuationLock, contributorEvidenceBatchSize, enrichOpenPullRequestsWithChangedFiles, processJob, reconcileLiveDuplicateSiblings, releaseAiReviewLock, releasePrActuationLock, reviewDurationMsSince, SWEEP_FANOUT_RESOLUTION_CONCURRENCY } from "../../src/queue/processors"; -import type { PullRequestRecord } from "../../src/types"; +import { claimAiReviewLock, claimPrActuationLock, processJob, releaseAiReviewLock, releasePrActuationLock, } from "../../src/queue/processors"; +import type { } from "../../src/types"; import { aiReviewCacheInputFingerprint } from "../../src/review/ai-review-cache-input"; -import { fingerprint as reviewMemoryFingerprint } from "../../src/review/review-memory-match"; +import { } from "../../src/review/review-memory-match"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; -import * as focusManifestLoaderModule from "../../src/signals/focus-manifest-loader"; import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { @@ -73,8 +39,6 @@ import { fetchPullRequestFreshness, } from "../../src/github/pr-freshness"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; -import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; -import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { @@ -122,33 +86,8 @@ function completeSegment(repoFullName: string, segment: "labels" | "open_issues" }; } -type CommandAnswerFixture = Parameters[1]; -function commandAnswer(id: string, command: string, overrides: Partial = {}): CommandAnswerFixture { - return { - id, - repoFullName: "JSONbored/gittensory", - issueNumber: 77, - command, - requestCommentId: 7, - responseCommentId: 9001, - responseUrl: "https://github.com/JSONbored/gittensory/pull/77#issuecomment-9001", - actorKind: "maintainer" as const, - createdAt: "2026-05-28T00:00:00.000Z", - updatedAt: "2026-05-28T00:00:00.000Z", - metadata: {}, - ...overrides, - }; -} -function commandAnswerBody(answerId: string, command: string): string { - return [ - "", - ``, - `Command: \`@loopover ${command}\``, - "Feedback is aggregate-only.", - ].join("\n"); -} function queueMinerSnapshot(login: string) { return { @@ -182,25 +121,7 @@ function queueMinerSnapshot(login: string) { }; } -function b64(value: string): string { - return Buffer.from(value, "utf8").toString("base64"); -} -function withProductUsageInsertFailure(env: Env): Env { - const db = env.DB as unknown as { prepare(sql: string): unknown; batch(statements: unknown[]): Promise }; - return { - ...env, - DB: { - prepare(sql: string) { - if (sql.includes("product_usage_events")) throw new Error("product usage insert failed"); - return db.prepare.call(db, sql); - }, - batch(statements: unknown[]) { - return db.batch.call(db, statements); - }, - } as unknown as D1Database, - }; -} describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows @@ -5621,7 +5542,7 @@ describe("queue processors", () => { await upsertOfficialMinerDetection(env, "contributor", { status: "confirmed", snapshot: queueMinerSnapshot("contributor") }, 60_000); // .loopover.yml authoritatively sets the linked-issue blocker to "block" (config-as-code, as in the gate tests above). await upsertRepoFocusManifest(env, "JSONbored/gittensory", { gate: { linkedIssue: "block" }, settings: { commentMode: "off", publicSurface: "off", checkRunMode: "off", reviewCheckMode: "required", linkedIssueGateMode: "block" } }); - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); if (url === "https://api.gittensor.io/miners") return Response.json([]); if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" }); diff --git a/test/unit/queue-3.test.ts b/test/unit/queue-3.test.ts index d64fc99b17..57d4097a58 100644 --- a/test/unit/queue-3.test.ts +++ b/test/unit/queue-3.test.ts @@ -1,81 +1,37 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { generateKeyPairSync } from "node:crypto"; +import { } from "node:crypto"; import { clearInstallationTokenCacheForTest } from "../../src/github/app"; import { clearReviewSuppressionCacheForTest } from "../../src/review/review-memory-wire"; -import { PR_PANEL_COMMENT_MARKER } from "../../src/github/comments"; -import * as backfillModule from "../../src/github/backfill"; -import * as rateLimitModule from "../../src/github/rate-limit"; +import { } from "../../src/github/comments"; import * as repositoriesModule from "../../src/db/repositories"; import * as visualCaptureModule from "../../src/review/visual/capture"; import { MAX_PREVIEW_POLL_ATTEMPTS } from "../../src/review/visual/preview-poll-budget"; -import * as reviewEffortModule from "../../src/review/review-effort"; import * as repositorySettingsModule from "../../src/settings/repository-settings"; -import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; -import { jobCoalesceKey } from "../../src/selfhost/queue-common"; +import { } from "../../src/selfhost/queue-common"; import { - listCollisionEdges, - createAgentRun, - getCommandUsefulnessSummary, - getBurdenForecast, - getContributorEvidence, - getAgentRun, - getContributorScoringProfile, - getWebhookEvent, - getInstallation, - getLatestUpstreamRulesetSnapshot, getPullRequest, - getPullRequestDetailSyncState, upsertPullRequestDetailSyncState, - getRepository, - listUpstreamDriftReports, - listInstallationHealth, - listProductUsageDailyRollups, - listProductUsageEvents, - listPullRequests, - listPullRequestFiles, - listRepoSyncStates, - listSignalSnapshots, - persistSignalSnapshot, - recordGateBlockOutcome, - markGateOutcomeOverridden, - recordProductUsageEvent, - upsertAgentCommandAnswer, - upsertCheckSummary, upsertIssueFromGitHub, - upsertRepoSyncSegment, upsertInstallation, - updatePullRequestSlopAssessment, upsertOfficialMinerDetection, - upsertPullRequestFile, upsertPullRequestFromGitHub, listOtherOpenPullRequestsForAuthor, - upsertIssueWatchSubscription, - upsertRepositoryAiKey, upsertRepositorySettings, upsertRepositoryFromGitHub, - putCachedAiReview, - markAiReviewPublished, - putCachedAiSlopAdvisory, - putCachedLinkedIssueSatisfaction, - recordReviewSuppression, - listReviewSuppressions, setGlobalAgentFrozen, } from "../../src/db/repositories"; -import { agentMaintenanceHeadMatchesGate, changedPathsForGuardrail, claimAiReviewLock, claimPrActuationLock, contributorEvidenceBatchSize, enrichOpenPullRequestsWithChangedFiles, processJob, reconcileLiveDuplicateSiblings, releaseAiReviewLock, releasePrActuationLock, reviewDurationMsSince, SWEEP_FANOUT_RESOLUTION_CONCURRENCY } from "../../src/queue/processors"; -import type { PullRequestRecord } from "../../src/types"; -import { aiReviewCacheInputFingerprint } from "../../src/review/ai-review-cache-input"; -import { fingerprint as reviewMemoryFingerprint } from "../../src/review/review-memory-match"; +import { processJob, } from "../../src/queue/processors"; +import type { } from "../../src/types"; +import { } from "../../src/review/ai-review-cache-input"; +import { } from "../../src/review/review-memory-match"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; import * as focusManifestLoaderModule from "../../src/signals/focus-manifest-loader"; -import { normalizeRegistryPayload } from "../../src/registry/normalize"; -import { persistRegistrySnapshot } from "../../src/registry/sync"; +import { } from "../../src/registry/normalize"; +import { } from "../../src/registry/sync"; import { - classifyPullRequestFreshness, fetchPullRequestFreshness, } from "../../src/github/pr-freshness"; import { createTestEnv } from "../helpers/d1"; -import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; -import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { @@ -91,65 +47,11 @@ vi.mock("../../src/github/pr-freshness", async (importOriginal) => { }; }); -// The re-gate sweep now FANS OUT the heavy re-review + marker stamp into per-PR `agent-regate-pr` jobs -// (#audit-sweep-fanout). A test asserting the re-review/stamp side effects must run the sweep AND drain the -// per-PR jobs it enqueues. Returns the captured agent-regate-pr jobs for assertions. -async function sweepAndDrainPerPr(env: Env, repoFullName: string): Promise { - const fanned: import("../../src/types").JobMessage[] = []; - const send = env.JOBS.send.bind(env.JOBS); - env.JOBS.send = (async (message: import("../../src/types").JobMessage, options?: QueueSendOptions) => { - if (message.type === "agent-regate-pr") fanned.push(message); - return send(message, options); - }) as typeof env.JOBS.send; - await processJob(env, { type: "agent-regate-sweep", requestedBy: "test", repoFullName }); - env.JOBS.send = send; - for (const job of fanned) await processJob(env, job); - return fanned; -} -function completeSegment(repoFullName: string, segment: "labels" | "open_issues" | "open_pull_requests") { - return { - repoFullName, - segment, - status: "complete" as const, - sourceKind: "test" as const, - mode: "resume" as const, - fetchedCount: 1, - expectedCount: 1, - pageCount: 1, - completedAt: "2026-05-25T00:00:00.000Z", - warnings: [], - }; -} -type CommandAnswerFixture = Parameters[1]; -function commandAnswer(id: string, command: string, overrides: Partial = {}): CommandAnswerFixture { - return { - id, - repoFullName: "JSONbored/gittensory", - issueNumber: 77, - command, - requestCommentId: 7, - responseCommentId: 9001, - responseUrl: "https://github.com/JSONbored/gittensory/pull/77#issuecomment-9001", - actorKind: "maintainer" as const, - createdAt: "2026-05-28T00:00:00.000Z", - updatedAt: "2026-05-28T00:00:00.000Z", - metadata: {}, - ...overrides, - }; -} -function commandAnswerBody(answerId: string, command: string): string { - return [ - "", - ``, - `Command: \`@loopover ${command}\``, - "Feedback is aggregate-only.", - ].join("\n"); -} function queueMinerSnapshot(login: string) { return { @@ -183,25 +85,7 @@ function queueMinerSnapshot(login: string) { }; } -function b64(value: string): string { - return Buffer.from(value, "utf8").toString("base64"); -} -function withProductUsageInsertFailure(env: Env): Env { - const db = env.DB as unknown as { prepare(sql: string): unknown; batch(statements: unknown[]): Promise }; - return { - ...env, - DB: { - prepare(sql: string) { - if (sql.includes("product_usage_events")) throw new Error("product usage insert failed"); - return db.prepare.call(db, sql); - }, - batch(statements: unknown[]) { - return db.batch.call(db, statements); - }, - } as unknown as D1Database, - }; -} describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows @@ -3975,7 +3859,6 @@ describe("queue processors", () => { const seen = { closed: false, cancelledIds: [] as number[], listedStatuses: [] as string[] }; vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { const url = input.toString(); - const method = init?.method ?? "GET"; if (url.includes("/actions/runs?head_sha=")) return Response.json({ message: "Resource not accessible by integration" }, { status: 403 }); return stubContributorCapCiCancelFetch(seen)(input, init); }); diff --git a/test/unit/queue-4.test.ts b/test/unit/queue-4.test.ts index 9908e614c4..033facaa19 100644 --- a/test/unit/queue-4.test.ts +++ b/test/unit/queue-4.test.ts @@ -1,83 +1,48 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { generateKeyPairSync } from "node:crypto"; +import { } from "node:crypto"; import { clearInstallationTokenCacheForTest } from "../../src/github/app"; import { clearReviewSuppressionCacheForTest } from "../../src/review/review-memory-wire"; -import { PR_PANEL_COMMENT_MARKER } from "../../src/github/comments"; +import { } from "../../src/github/comments"; import * as backfillModule from "../../src/github/backfill"; -import * as rateLimitModule from "../../src/github/rate-limit"; import * as repositoriesModule from "../../src/db/repositories"; import * as reviewEffortModule from "../../src/review/review-effort"; -import * as repositorySettingsModule from "../../src/settings/repository-settings"; import * as posthogModule from "../../src/selfhost/posthog"; -import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; -import { jobCoalesceKey } from "../../src/selfhost/queue-common"; +import { } from "../../src/selfhost/queue-common"; import { - listCollisionEdges, - createAgentRun, getCommandUsefulnessSummary, - getBurdenForecast, - getContributorEvidence, - getAgentRun, - getContributorScoringProfile, - getWebhookEvent, - getInstallation, - getLatestUpstreamRulesetSnapshot, getPullRequest, - getPullRequestDetailSyncState, upsertPullRequestDetailSyncState, - getRepository, - listUpstreamDriftReports, - listInstallationHealth, - listProductUsageDailyRollups, listProductUsageEvents, listPullRequests, - listPullRequestFiles, - listRepoSyncStates, - listSignalSnapshots, - persistSignalSnapshot, - recordGateBlockOutcome, - markGateOutcomeOverridden, - recordProductUsageEvent, upsertAgentCommandAnswer, upsertCheckSummary, upsertIssueFromGitHub, - upsertRepoSyncSegment, upsertInstallation, - updatePullRequestSlopAssessment, upsertOfficialMinerDetection, upsertPullRequestFile, upsertPullRequestFromGitHub, - upsertIssueWatchSubscription, upsertRepositoryAiKey, upsertRepositorySettings, upsertRepositoryFromGitHub, putCachedAiReview, markAiReviewPublished, - putCachedAiSlopAdvisory, - putCachedLinkedIssueSatisfaction, recordReviewSuppression, - listReviewSuppressions, - setGlobalAgentFrozen, persistAdvisory, } from "../../src/db/repositories"; -import { agentMaintenanceHeadMatchesGate, changedPathsForGuardrail, claimAiReviewLock, claimPrActuationLock, contributorEvidenceBatchSize, enrichOpenPullRequestsWithChangedFiles, processJob, reconcileLiveDuplicateSiblings, releaseAiReviewLock, releasePrActuationLock, reviewDurationMsSince, SWEEP_FANOUT_RESOLUTION_CONCURRENCY } from "../../src/queue/processors"; -import type { PullRequestRecord } from "../../src/types"; -import { aiReviewCacheInputFingerprint } from "../../src/review/ai-review-cache-input"; +import { claimPrActuationLock, processJob, releasePrActuationLock, } from "../../src/queue/processors"; +import type { } from "../../src/types"; +import { } from "../../src/review/ai-review-cache-input"; import { fingerprint as reviewMemoryFingerprint } from "../../src/review/review-memory-match"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; import * as pixelDiffModule from "../../src/review/visual/pixel-diff"; import * as scrollGifModule from "../../src/review/visual/scroll-gif"; import * as shotModule from "../../src/review/visual/shot"; -import * as focusManifestLoaderModule from "../../src/signals/focus-manifest-loader"; import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { - classifyPullRequestFreshness, fetchPullRequestFreshness, } from "../../src/github/pr-freshness"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; -import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; -import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; import { AI_REVIEW_CACHE_INPUT_VERSION } from "../../src/review/ai-review-cache-input"; @@ -111,20 +76,6 @@ async function sweepAndDrainPerPr(env: Env, repoFullName: string): Promise[1]; @@ -186,25 +137,7 @@ function queueMinerSnapshot(login: string) { }; } -function b64(value: string): string { - return Buffer.from(value, "utf8").toString("base64"); -} -function withProductUsageInsertFailure(env: Env): Env { - const db = env.DB as unknown as { prepare(sql: string): unknown; batch(statements: unknown[]): Promise }; - return { - ...env, - DB: { - prepare(sql: string) { - if (sql.includes("product_usage_events")) throw new Error("product usage insert failed"); - return db.prepare.call(db, sql); - }, - batch(statements: unknown[]) { - return db.batch.call(db, statements); - }, - } as unknown as D1Database, - }; -} describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows diff --git a/test/unit/queue-5.test.ts b/test/unit/queue-5.test.ts index 6eb6d4ed58..eaa979f4b4 100644 --- a/test/unit/queue-5.test.ts +++ b/test/unit/queue-5.test.ts @@ -1,48 +1,20 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { generateKeyPairSync } from "node:crypto"; +import { } from "node:crypto"; import { clearInstallationTokenCacheForTest } from "../../src/github/app"; import { clearReviewSuppressionCacheForTest } from "../../src/review/review-memory-wire"; import { clearOpsManifestOverrideCacheForTest } from "../../src/review/ops-wire"; import { clearLoopEscalationManifestOverrideCacheForTest } from "../../src/review/loop-escalation-wire"; -import { PR_PANEL_COMMENT_MARKER } from "../../src/github/comments"; +import { } from "../../src/github/comments"; import * as backfillModule from "../../src/github/backfill"; -import * as rateLimitModule from "../../src/github/rate-limit"; import * as repositoriesModule from "../../src/db/repositories"; -import * as reviewEffortModule from "../../src/review/review-effort"; import * as repositorySettingsModule from "../../src/settings/repository-settings"; -import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; import { jobCoalesceKey } from "../../src/selfhost/queue-common"; import { - listCollisionEdges, - createAgentRun, - getCommandUsefulnessSummary, - getBurdenForecast, - getContributorEvidence, - getAgentRun, - getContributorScoringProfile, - getWebhookEvent, - getInstallation, - getLatestUpstreamRulesetSnapshot, getPullRequest, getPullRequestDetailSyncState, - upsertPullRequestDetailSyncState, - getRepository, - listUpstreamDriftReports, - listInstallationHealth, - listProductUsageDailyRollups, listProductUsageEvents, - listPullRequests, - listPullRequestFiles, - listRepoSyncStates, - listSignalSnapshots, - persistSignalSnapshot, recordGateBlockOutcome, - markGateOutcomeOverridden, - recordProductUsageEvent, - upsertAgentCommandAnswer, - upsertCheckSummary, upsertIssueFromGitHub, - upsertRepoSyncSegment, upsertInstallation, updatePullRequestSlopAssessment, upsertOfficialMinerDetection, @@ -54,27 +26,19 @@ import { upsertRepositoryFromGitHub, putCachedAiReview, markAiReviewPublished, - putCachedAiSlopAdvisory, - putCachedLinkedIssueSatisfaction, - recordReviewSuppression, listReviewSuppressions, - setGlobalAgentFrozen, } from "../../src/db/repositories"; -import { agentMaintenanceHeadMatchesGate, changedPathsForGuardrail, claimAiReviewLock, claimPrActuationLock, contributorEvidenceBatchSize, enrichOpenPullRequestsWithChangedFiles, processJob, reconcileLiveDuplicateSiblings, releaseAiReviewLock, releasePrActuationLock, reviewDurationMsSince, SWEEP_FANOUT_RESOLUTION_CONCURRENCY } from "../../src/queue/processors"; -import type { PullRequestRecord } from "../../src/types"; -import { aiReviewCacheInputFingerprint } from "../../src/review/ai-review-cache-input"; -import { fingerprint as reviewMemoryFingerprint } from "../../src/review/review-memory-match"; +import { claimPrActuationLock, processJob, releasePrActuationLock, } from "../../src/queue/processors"; +import type { } from "../../src/types"; +import { } from "../../src/review/ai-review-cache-input"; +import { } from "../../src/review/review-memory-match"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; -import * as focusManifestLoaderModule from "../../src/signals/focus-manifest-loader"; import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { - classifyPullRequestFreshness, fetchPullRequestFreshness, } from "../../src/github/pr-freshness"; import { createTestEnv } from "../helpers/d1"; -import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; -import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { @@ -90,65 +54,11 @@ vi.mock("../../src/github/pr-freshness", async (importOriginal) => { }; }); -// The re-gate sweep now FANS OUT the heavy re-review + marker stamp into per-PR `agent-regate-pr` jobs -// (#audit-sweep-fanout). A test asserting the re-review/stamp side effects must run the sweep AND drain the -// per-PR jobs it enqueues. Returns the captured agent-regate-pr jobs for assertions. -async function sweepAndDrainPerPr(env: Env, repoFullName: string): Promise { - const fanned: import("../../src/types").JobMessage[] = []; - const send = env.JOBS.send.bind(env.JOBS); - env.JOBS.send = (async (message: import("../../src/types").JobMessage, options?: QueueSendOptions) => { - if (message.type === "agent-regate-pr") fanned.push(message); - return send(message, options); - }) as typeof env.JOBS.send; - await processJob(env, { type: "agent-regate-sweep", requestedBy: "test", repoFullName }); - env.JOBS.send = send; - for (const job of fanned) await processJob(env, job); - return fanned; -} -function completeSegment(repoFullName: string, segment: "labels" | "open_issues" | "open_pull_requests") { - return { - repoFullName, - segment, - status: "complete" as const, - sourceKind: "test" as const, - mode: "resume" as const, - fetchedCount: 1, - expectedCount: 1, - pageCount: 1, - completedAt: "2026-05-25T00:00:00.000Z", - warnings: [], - }; -} -type CommandAnswerFixture = Parameters[1]; -function commandAnswer(id: string, command: string, overrides: Partial = {}): CommandAnswerFixture { - return { - id, - repoFullName: "JSONbored/gittensory", - issueNumber: 77, - command, - requestCommentId: 7, - responseCommentId: 9001, - responseUrl: "https://github.com/JSONbored/gittensory/pull/77#issuecomment-9001", - actorKind: "maintainer" as const, - createdAt: "2026-05-28T00:00:00.000Z", - updatedAt: "2026-05-28T00:00:00.000Z", - metadata: {}, - ...overrides, - }; -} -function commandAnswerBody(answerId: string, command: string): string { - return [ - "", - ``, - `Command: \`@loopover ${command}\``, - "Feedback is aggregate-only.", - ].join("\n"); -} function queueMinerSnapshot(login: string) { return { @@ -182,9 +92,6 @@ function queueMinerSnapshot(login: string) { }; } -function b64(value: string): string { - return Buffer.from(value, "utf8").toString("base64"); -} function withProductUsageInsertFailure(env: Env): Env { const db = env.DB as unknown as { prepare(sql: string): unknown; batch(statements: unknown[]): Promise }; @@ -2213,7 +2120,7 @@ describe("queue processors", () => { body: "", }); const calls = { comments: 0, permission: 0 }; - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" }); // The commenter is an org MEMBER but has only READ access to THIS repo — not a maintainer/collaborator. @@ -3651,9 +3558,8 @@ describe("queue processors", () => { body: "Validation: npm test", }); const calls = { token: 0, permission: 0, checkGets: 0, checkPatches: 0, comments: 0 }; - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); - const method = init?.method ?? "GET"; if (url.includes("/access_tokens")) { calls.token += 1; return Response.json({ token: "installation-token" }); diff --git a/test/unit/queue-lifecycle-guards.test.ts b/test/unit/queue-lifecycle-guards.test.ts index c531d78aae..acb36baf08 100644 --- a/test/unit/queue-lifecycle-guards.test.ts +++ b/test/unit/queue-lifecycle-guards.test.ts @@ -2,78 +2,38 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { generateKeyPairSync } from "node:crypto"; import { clearInstallationTokenCacheForTest } from "../../src/github/app"; import { jobClaimSortKey } from "../../src/selfhost/queue-common"; -import { clearReviewSuppressionCacheForTest } from "../../src/review/review-memory-wire"; -import { PR_PANEL_COMMENT_MARKER } from "../../src/github/comments"; -import * as backfillModule from "../../src/github/backfill"; -import * as rateLimitModule from "../../src/github/rate-limit"; +import { } from "../../src/review/review-memory-wire"; +import { } from "../../src/github/comments"; import * as repositoriesModule from "../../src/db/repositories"; -import * as reviewEffortModule from "../../src/review/review-effort"; import * as repositorySettingsModule from "../../src/settings/repository-settings"; import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; -import { jobCoalesceKey } from "../../src/selfhost/queue-common"; +import { } from "../../src/selfhost/queue-common"; import { - listCollisionEdges, - createAgentRun, - getCommandUsefulnessSummary, - getBurdenForecast, - getContributorEvidence, - getAgentRun, - getContributorScoringProfile, - getWebhookEvent, getInstallation, - getLatestUpstreamRulesetSnapshot, getPullRequest, getPullRequestDetailSyncState, upsertPullRequestDetailSyncState, - getRepository, - listUpstreamDriftReports, - listInstallationHealth, - listProductUsageDailyRollups, - listProductUsageEvents, - listPullRequests, - listPullRequestFiles, - listRepoSyncStates, - listSignalSnapshots, - persistSignalSnapshot, recordGateBlockOutcome, markGateOutcomeOverridden, - recordProductUsageEvent, - upsertAgentCommandAnswer, - upsertCheckSummary, - upsertIssueFromGitHub, - upsertRepoSyncSegment, upsertInstallation, - updatePullRequestSlopAssessment, upsertOfficialMinerDetection, upsertPullRequestFile, upsertPullRequestFromGitHub, - upsertIssueWatchSubscription, - upsertRepositoryAiKey, upsertRepositorySettings, upsertRepositoryFromGitHub, - putCachedAiReview, - markAiReviewPublished, - putCachedAiSlopAdvisory, - putCachedLinkedIssueSatisfaction, - recordReviewSuppression, - listReviewSuppressions, - setGlobalAgentFrozen, } from "../../src/db/repositories"; -import { agentMaintenanceHeadMatchesGate, changedPathsForGuardrail, claimAiReviewLock, claimPrActuationLock, contributorEvidenceBatchSize, enrichOpenPullRequestsWithChangedFiles, processJob, reconcileLiveDuplicateSiblings, releaseAiReviewLock, releasePrActuationLock, reviewDurationMsSince, SWEEP_FANOUT_RESOLUTION_CONCURRENCY } from "../../src/queue/processors"; +import { agentMaintenanceHeadMatchesGate, changedPathsForGuardrail, enrichOpenPullRequestsWithChangedFiles, processJob, reconcileLiveDuplicateSiblings, SWEEP_FANOUT_RESOLUTION_CONCURRENCY } from "../../src/queue/processors"; import type { PullRequestRecord } from "../../src/types"; -import { aiReviewCacheInputFingerprint } from "../../src/review/ai-review-cache-input"; -import { fingerprint as reviewMemoryFingerprint } from "../../src/review/review-memory-match"; +import { } from "../../src/review/ai-review-cache-input"; +import { } from "../../src/review/review-memory-match"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; import * as focusManifestLoaderModule from "../../src/signals/focus-manifest-loader"; import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { - classifyPullRequestFreshness, fetchPullRequestFreshness, } from "../../src/github/pr-freshness"; import { createTestEnv } from "../helpers/d1"; -import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; -import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { @@ -89,65 +49,11 @@ vi.mock("../../src/github/pr-freshness", async (importOriginal) => { }; }); -// The re-gate sweep now FANS OUT the heavy re-review + marker stamp into per-PR `agent-regate-pr` jobs -// (#audit-sweep-fanout). A test asserting the re-review/stamp side effects must run the sweep AND drain the -// per-PR jobs it enqueues. Returns the captured agent-regate-pr jobs for assertions. -async function sweepAndDrainPerPr(env: Env, repoFullName: string): Promise { - const fanned: import("../../src/types").JobMessage[] = []; - const send = env.JOBS.send.bind(env.JOBS); - env.JOBS.send = (async (message: import("../../src/types").JobMessage, options?: QueueSendOptions) => { - if (message.type === "agent-regate-pr") fanned.push(message); - return send(message, options); - }) as typeof env.JOBS.send; - await processJob(env, { type: "agent-regate-sweep", requestedBy: "test", repoFullName }); - env.JOBS.send = send; - for (const job of fanned) await processJob(env, job); - return fanned; -} -function completeSegment(repoFullName: string, segment: "labels" | "open_issues" | "open_pull_requests") { - return { - repoFullName, - segment, - status: "complete" as const, - sourceKind: "test" as const, - mode: "resume" as const, - fetchedCount: 1, - expectedCount: 1, - pageCount: 1, - completedAt: "2026-05-25T00:00:00.000Z", - warnings: [], - }; -} -type CommandAnswerFixture = Parameters[1]; -function commandAnswer(id: string, command: string, overrides: Partial = {}): CommandAnswerFixture { - return { - id, - repoFullName: "JSONbored/gittensory", - issueNumber: 77, - command, - requestCommentId: 7, - responseCommentId: 9001, - responseUrl: "https://github.com/JSONbored/gittensory/pull/77#issuecomment-9001", - actorKind: "maintainer" as const, - createdAt: "2026-05-28T00:00:00.000Z", - updatedAt: "2026-05-28T00:00:00.000Z", - metadata: {}, - ...overrides, - }; -} -function commandAnswerBody(answerId: string, command: string): string { - return [ - "", - ``, - `Command: \`@loopover ${command}\``, - "Feedback is aggregate-only.", - ].join("\n"); -} function queueMinerSnapshot(login: string) { return { @@ -181,25 +87,7 @@ function queueMinerSnapshot(login: string) { }; } -function b64(value: string): string { - return Buffer.from(value, "utf8").toString("base64"); -} -function withProductUsageInsertFailure(env: Env): Env { - const db = env.DB as unknown as { prepare(sql: string): unknown; batch(statements: unknown[]): Promise }; - return { - ...env, - DB: { - prepare(sql: string) { - if (sql.includes("product_usage_events")) throw new Error("product usage insert failed"); - return db.prepare.call(db, sql); - }, - batch(statements: unknown[]) { - return db.batch.call(db, statements); - }, - } as unknown as D1Database, - }; -} describe("changedPathsForGuardrail", () => { it("collects current + rename paths and skips empty entries", () => { @@ -660,7 +548,7 @@ describe("one-shot reopen prevention", () => { }); it("swallows a recordAuditEvent failure on the stale-reopen denial path — handler still completes (#2130)", async () => { - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" }); if (url.endsWith("/collaborators/contributor/permission")) return Response.json({ permission: "read" }); @@ -979,7 +867,7 @@ describe("one-shot reopen prevention", () => { }); it("swallows createIssueComment, closePullRequest, and recordAuditEvent errors on reclose (fail-safe — all .catch() bodies)", async () => { - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); if (url.includes("/access_tokens")) return Response.json({ token: "t" }); if (url.endsWith("/collaborators/contributor/permission")) return Response.json({ permission: "read" }); @@ -1271,7 +1159,7 @@ describe("converted_to_draft gate-close (draft-dodge prevention)", () => { }); it("swallows a recordAuditEvent failure on the stale-draft-dodge denial path — handler still completes (#2130)", async () => { - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); if (url.includes("/access_tokens")) return Response.json({ token: "t" }); return new Response("not found", { status: 404 }); @@ -1677,7 +1565,7 @@ describe("converted_to_draft gate-close (draft-dodge prevention)", () => { }); it("swallows createIssueComment and closePullRequest API errors (fail-safe — both .catch() bodies)", async () => { - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); if (url.includes("/access_tokens")) return Response.json({ token: "t" }); throw new Error("simulated network error"); // all GitHub calls throw @@ -5428,9 +5316,8 @@ describe("auto-action convergence: end-to-end plan+execute for the general heuri scheduled.push(options ? { message, options } : { message }); return originalSend(message, options); }) as typeof env.JOBS.send; - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); - const method = init?.method ?? "GET"; if (url === "https://api.gittensor.io/miners") return Response.json([]); if (url === "https://api.github.com/graphql") { return Response.json({ data: { repository: { pullRequest: { reviewDecision: "APPROVED" } } } }); diff --git a/test/unit/queue.test.ts b/test/unit/queue.test.ts index 36daf3dd5b..013b2b4c47 100644 --- a/test/unit/queue.test.ts +++ b/test/unit/queue.test.ts @@ -1,82 +1,65 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { generateKeyPairSync } from "node:crypto"; +import { } from "node:crypto"; import { clearInstallationTokenCacheForTest } from "../../src/github/app"; import { clearReviewSuppressionCacheForTest } from "../../src/review/review-memory-wire"; -import { PR_PANEL_COMMENT_MARKER } from "../../src/github/comments"; +import { } from "../../src/github/comments"; import * as commentsModule from "../../src/github/comments"; import * as backfillModule from "../../src/github/backfill"; import * as rateLimitModule from "../../src/github/rate-limit"; import * as repositoriesModule from "../../src/db/repositories"; -import * as reviewEffortModule from "../../src/review/review-effort"; import * as repositorySettingsModule from "../../src/settings/repository-settings"; import { counterValue, renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; import { REQUIRED_CONTEXTS_UNRESOLVED_METRIC } from "../../src/queue/ci-resolution"; -import { jobCoalesceKey } from "../../src/selfhost/queue-common"; +import { } from "../../src/selfhost/queue-common"; import { VERDICT_FLIP_ESCALATION_THRESHOLD } from "../../src/review/verdict-flip-guard"; import { listCollisionEdges, createAgentRun, - getCommandUsefulnessSummary, getBurdenForecast, getContributorEvidence, getAgentRun, getContributorScoringProfile, getWebhookEvent, - getInstallation, getLatestUpstreamRulesetSnapshot, getPullRequest, getPullRequestDetailSyncState, upsertPullRequestDetailSyncState, - getRepository, listUpstreamDriftReports, - listInstallationHealth, listProductUsageDailyRollups, listProductUsageEvents, - listPullRequests, - listPullRequestFiles, listRepoSyncStates, listSignalSnapshots, persistSignalSnapshot, - recordGateBlockOutcome, - markGateOutcomeOverridden, recordProductUsageEvent, - upsertAgentCommandAnswer, upsertCheckSummary, upsertIssueFromGitHub, upsertRepoSyncSegment, upsertInstallation, - updatePullRequestSlopAssessment, upsertOfficialMinerDetection, upsertPullRequestFile, upsertPullRequestFromGitHub, - upsertIssueWatchSubscription, - upsertRepositoryAiKey, upsertRepositorySettings, upsertRepositoryFromGitHub, putCachedAiReview, markAiReviewPublished, putCachedAiSlopAdvisory, putCachedLinkedIssueSatisfaction, - recordReviewSuppression, - listReviewSuppressions, - setGlobalAgentFrozen, } from "../../src/db/repositories"; -import { agentMaintenanceHeadMatchesGate, buildBurdenForecasts, changedPathsForGuardrail, claimAiReviewLock, claimPrActuationLock, contributorEvidenceBatchSize, enrichOpenPullRequestsWithChangedFiles, fanOutRepoSignalSnapshotJobs, processJob, reconcileLiveDuplicateSiblings, releaseAiReviewLock, releasePrActuationLock, reviewDurationMsSince, SWEEP_FANOUT_RESOLUTION_CONCURRENCY } from "../../src/queue/processors"; -import type { PullRequestRecord } from "../../src/types"; +import { buildBurdenForecasts, claimAiReviewLock, contributorEvidenceBatchSize, fanOutRepoSignalSnapshotJobs, processJob, reviewDurationMsSince, SWEEP_FANOUT_RESOLUTION_CONCURRENCY } from "../../src/queue/processors"; +import type { } from "../../src/types"; import { aiReviewCacheInputFingerprint } from "../../src/review/ai-review-cache-input"; -import { fingerprint as reviewMemoryFingerprint } from "../../src/review/review-memory-match"; +import { } from "../../src/review/review-memory-match"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; import * as focusManifestLoaderModule from "../../src/signals/focus-manifest-loader"; import * as rulesetModule from "../../src/upstream/ruleset"; import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { - classifyPullRequestFreshness, fetchPullRequestFreshness, } from "../../src/github/pr-freshness"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; -import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; +import { AGENT_LABEL_PENDING_CLOSURE, } from "../../src/review/linked-issue-hard-rules"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { @@ -124,33 +107,8 @@ function completeSegment(repoFullName: string, segment: "labels" | "open_issues" }; } -type CommandAnswerFixture = Parameters[1]; -function commandAnswer(id: string, command: string, overrides: Partial = {}): CommandAnswerFixture { - return { - id, - repoFullName: "JSONbored/gittensory", - issueNumber: 77, - command, - requestCommentId: 7, - responseCommentId: 9001, - responseUrl: "https://github.com/JSONbored/gittensory/pull/77#issuecomment-9001", - actorKind: "maintainer" as const, - createdAt: "2026-05-28T00:00:00.000Z", - updatedAt: "2026-05-28T00:00:00.000Z", - metadata: {}, - ...overrides, - }; -} -function commandAnswerBody(answerId: string, command: string): string { - return [ - "", - ``, - `Command: \`@loopover ${command}\``, - "Feedback is aggregate-only.", - ].join("\n"); -} function queueMinerSnapshot(login: string) { return { @@ -188,21 +146,6 @@ function b64(value: string): string { return Buffer.from(value, "utf8").toString("base64"); } -function withProductUsageInsertFailure(env: Env): Env { - const db = env.DB as unknown as { prepare(sql: string): unknown; batch(statements: unknown[]): Promise }; - return { - ...env, - DB: { - prepare(sql: string) { - if (sql.includes("product_usage_events")) throw new Error("product usage insert failed"); - return db.prepare.call(db, sql); - }, - batch(statements: unknown[]) { - return db.batch.call(db, statements); - }, - } as unknown as D1Database, - }; -} describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows @@ -7707,9 +7650,8 @@ describe("queue processors", () => { }); await seedRegateChurnRepo(env); await upsertPullRequestFromGitHub(env, "JSONbored/gittensory", { number: 95, title: "Held behind an orphaned AI-review lock", state: "open", user: { login: "contributor" }, head: { sha: "a95" }, labels: [], body: "Closes #1" }); - vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + vi.stubGlobal("fetch", async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); - const method = init?.method ?? "GET"; if (url.includes("/access_tokens")) return Response.json({ token: "fake-installation-token" }); if (url.includes("/collaborators/maintainer/permission")) return Response.json({ permission: "maintain" }); if (url.includes("/pulls/95/files")) return Response.json([{ filename: "src/a.ts", status: "modified", additions: 1, deletions: 0, changes: 1, patch: "@@\n+export const ok = true;" }]); diff --git a/test/unit/review-evasion-per-repo-admin.test.ts b/test/unit/review-evasion-per-repo-admin.test.ts index 71c859efed..183ccb4761 100644 --- a/test/unit/review-evasion-per-repo-admin.test.ts +++ b/test/unit/review-evasion-per-repo-admin.test.ts @@ -9,14 +9,6 @@ import { createTestEnv } from "../helpers/d1"; import type { GitHubWebhookPayload, PullRequestRecord, RepositorySettings } from "../../src/types"; import { generatePrivateKeyPem } from "../helpers/github-app-key"; -// #4889: the review-evasion guards' fleet-operator exemptions in per-repo admin mode. Mode OFF (self-host -// default) keeps the ADMIN_GITHUB_LOGINS shortcut byte-identical — an allowlisted actor is exempt with NO -// GitHub permission lookup. Mode ON drops that shortcut: the live per-repo collaborator permission is the -// sole non-owner permission source, so an allowlisted login with no real access on THIS repo stops being -// exempt. Each test pins which path ran by inspecting exactly which GitHub API calls the guard made. - -const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" "); -const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" "); type StubHandler = (url: string) => Response | undefined; diff --git a/test/unit/review-grounding.test.ts b/test/unit/review-grounding.test.ts index 1287c21d37..f5ccfcba83 100644 --- a/test/unit/review-grounding.test.ts +++ b/test/unit/review-grounding.test.ts @@ -3,7 +3,6 @@ import { buildGrounding, diffFilePriority, diffFullyCoversFile, - FILE_CONTENT_BUDGET, fetchFullFileContents, type FileFetcher, formatGroundingSections, diff --git a/test/unit/routes-issue-plan-draft.test.ts b/test/unit/routes-issue-plan-draft.test.ts index 1c7ed17f35..cfa0602949 100644 --- a/test/unit/routes-issue-plan-draft.test.ts +++ b/test/unit/routes-issue-plan-draft.test.ts @@ -1,4 +1,4 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { createApp } from "../../src/api/routes"; import { createSessionForGitHubUser } from "../../src/auth/security"; import { upsertInstallation, upsertPullRequestFromGitHub, upsertRepositoryFromGitHub } from "../../src/db/repositories"; diff --git a/test/unit/screenshot-evidence-summary-wiring.test.ts b/test/unit/screenshot-evidence-summary-wiring.test.ts index 270b58e5b8..c0148fa923 100644 --- a/test/unit/screenshot-evidence-summary-wiring.test.ts +++ b/test/unit/screenshot-evidence-summary-wiring.test.ts @@ -65,9 +65,8 @@ async function runWebhookPass(args: { const pullPath = `/pulls/${args.pull}`; vi.stubGlobal( "fetch", - vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + vi.fn(async (input: RequestInfo | URL, _init?: RequestInit) => { const url = input.toString(); - const method = init?.method ?? "GET"; if (url === "https://api.gittensor.io/miners") return Response.json([]); if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" }); if (url === BEFORE_URL) return new Response(new Uint8Array([1, 2, 3]), { status: 200, headers: { "content-type": "image/png" } }); diff --git a/test/unit/selfhost-pg-queue.test.ts b/test/unit/selfhost-pg-queue.test.ts index 8ca1b757de..aa7a7d8ffe 100644 --- a/test/unit/selfhost-pg-queue.test.ts +++ b/test/unit/selfhost-pg-queue.test.ts @@ -435,7 +435,7 @@ describe("createPgQueue (durable #977)", () => { const priorityUpdateSql = "UPDATE _selfhost_jobs SET priority=$1"; const jobKeyUpdateSql = "UPDATE _selfhost_jobs SET job_key=$1"; const claimSortUpdateSql = "UPDATE _selfhost_jobs SET claim_sort_key=$1"; - const fn = vi.fn().mockImplementation(async (sql: unknown, params?: unknown[]) => { + const fn = vi.fn().mockImplementation(async (sql: unknown, _params?: unknown[]) => { const q = String(sql); if (q.includes("SELECT id, payload, priority")) { return { diff --git a/test/unit/selfhost-pg-vectorize.test.ts b/test/unit/selfhost-pg-vectorize.test.ts index e87dfdf0c1..f45dc96013 100644 --- a/test/unit/selfhost-pg-vectorize.test.ts +++ b/test/unit/selfhost-pg-vectorize.test.ts @@ -1,7 +1,7 @@ // Unit tests for pg-vectorize (#980 pgvector RAG). Uses a mock pg Pool so no real Postgres is required. // The integration path (initPgVectorize + real Postgres) is covered by selfhost-pg-queue.test.ts (which // already spins up Postgres in CI via the pg integration harness). -import { describe, expect, it, vi, beforeEach } from "vitest"; +import { describe, expect, it, beforeEach } from "vitest"; import { createPgVectorize, initPgVectorize } from "../../src/selfhost/pg-vectorize"; import type { Pool } from "pg"; diff --git a/test/unit/selfhost-redis-response-cache.test.ts b/test/unit/selfhost-redis-response-cache.test.ts index c7406b8b5b..3f01b6b659 100644 --- a/test/unit/selfhost-redis-response-cache.test.ts +++ b/test/unit/selfhost-redis-response-cache.test.ts @@ -1,6 +1,6 @@ import type { Redis } from "ioredis"; import { afterEach, describe, expect, it } from "vitest"; -import { counterValue, incr, renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; +import { incr, renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; import { createRedisResponseCache } from "../../src/selfhost/redis-response-cache"; function fakeRedis(): { diff --git a/test/unit/signals-edge-cases.test.ts b/test/unit/signals-edge-cases.test.ts index 7505126257..52f420d644 100644 --- a/test/unit/signals-edge-cases.test.ts +++ b/test/unit/signals-edge-cases.test.ts @@ -44,7 +44,6 @@ import { PREFLIGHT_LIMITS } from "../../src/signals/preflight-limits"; import { REVIEW_FIELD_KEYS } from "../../src/signals/focus-manifest"; import type { GittensorContributorSnapshot } from "../../src/gittensor/api"; import type { - ContributorRepoStatRecord, CheckSummaryRecord, IssueRecord, PullRequestFileRecord, diff --git a/test/unit/signals.test.ts b/test/unit/signals.test.ts index b9e54a6d31..fdf696a3f1 100644 --- a/test/unit/signals.test.ts +++ b/test/unit/signals.test.ts @@ -31,7 +31,7 @@ import { shouldPublishPrIntelligenceComment, type CollisionReport, } from "../../src/signals/engine"; -import { GITTENSOR_HOME_URL } from "../../src/github/footer"; +import { } from "../../src/github/footer"; import type { BountyRecord, CheckSummaryRecord, @@ -557,18 +557,6 @@ describe("world-class backend signals", () => { aiReviewByok: false, aiReviewAllAuthors: false, closeOwnerAuthors: false, }; - const collisions = buildCollisionReport(repo.fullName, issues, pullRequests); - const queueHealth = buildQueueHealth(repo, issues, pullRequests, collisions); - const preflight = buildPreflightResult( - { repoFullName: repo.fullName, title: currentPr.title, body: "Fixes #7", linkedIssues: [7] }, - repo, - issues, - pullRequests, - ); - const profile = buildContributorProfile("oktofeesh1", { login: "oktofeesh1", topLanguages: ["TypeScript"], source: "github" }, [ - currentPr, - priorPr, - ], []); expect(detection.detected).toBe(true); expect(shouldPublishPrIntelligenceComment(settings, detection)).toBe(true); }); diff --git a/tsconfig.json b/tsconfig.json index 77ee066bed..761bffe908 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,14 @@ "exactOptionalPropertyTypes": true, "noImplicitOverride": true, "noFallthroughCasesInSwitch": true, + // #9553. Dead code is the substrate every drift bug in the 2026-07-27 audit grew on: a stale import or an + // orphaned constant reads exactly like a live wire, so the next person greps, finds it, and reasons about + // a code path that no longer runs. Enabling these made the compiler enumerate all 515 instances, and + // triaging them found three real (if latent) problems that were invisible while the noise was tolerated -- + // see this commit's message. Unused PARAMETERS are positional, so silence one with a leading underscore + // (`_unusedArg`), which tsc honours by design; never delete it, or every later argument silently re-binds. + "noUnusedLocals": true, + "noUnusedParameters": true, "skipLibCheck": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, From e2d516cb2ad2a1469796036cb8f9a2a49456630c Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 28 Jul 2026 04:41:41 -0700 Subject: [PATCH 2/5] chore(engine): bump to 3.15.4 for the dead type-import removal in gate-advisory.ts check-engine-parity holds the two hand-duplicated gate-decision twins (packages/loopover-engine/src/advisory/gate-advisory.ts and src/rules/advisory.ts) in lockstep: touching one without the other requires an engine version bump. That is the mechanism, and it is doing its job here. the engine twin. They are genuinely dead there and NOT in the host: the engine copy is a deliberately slimmed re-implementation (#4881) that omits buildIssueAdvisory / addIssueFindings / collisionClustersForPull, which are what use those types on the host side. So there is no matching host edit to make -- the asymmetry is correct, and the version bump is the sanctioned way to record it. No behaviour change: type-only imports are erased at compile time. The bump exists so the parity contract stays enforceable, not because the gate decides anything differently. packages/loopover-miner/expected-engine.version moves in lockstep, as its own check requires. --- packages/loopover-engine/package.json | 2 +- packages/loopover-miner/expected-engine.version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/loopover-engine/package.json b/packages/loopover-engine/package.json index 5c709cae48..c58db537fe 100644 --- a/packages/loopover-engine/package.json +++ b/packages/loopover-engine/package.json @@ -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.", diff --git a/packages/loopover-miner/expected-engine.version b/packages/loopover-miner/expected-engine.version index 1eeac129c5..ffaa55f596 100644 --- a/packages/loopover-miner/expected-engine.version +++ b/packages/loopover-miner/expected-engine.version @@ -1 +1 @@ -3.16.0 +3.16.1 From 7c8a683617d8cac629fea0794031dbfb2246a5b7 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 28 Jul 2026 04:59:07 -0700 Subject: [PATCH 3/5] fix(scripts,mcp): restore actionlint's `.ts` specifier and drop a dead shape #9565 added Two rebase follow-ups after #9565 and #9574 landed. 1. scripts/actionlint.ts gets its `.ts` extension back. This PR had removed it to satisfy check-import-specifiers, which broke the script outright -- it runs under `node --experimental-strip-types`, whose ESM resolver does no extension resolution, so the process dies at startup with ERR_MODULE_NOT_FOUND. #9565 independently reached the same conclusion and added TYPE_STRIPPED_ENTRYPOINTS to the checker for exactly this file, so the extension is now permitted where it is required. Verified by running `npm run actionlint`, which fails before this change and passes after. #9565's version of the checker is taken wholesale over this PR's: it solves the same two problems (that entrypoint set, plus allowlisting check-dead-source-files-script.test.ts for its string fixtures), and re-litigating a file main just rewrote buys nothing. 2. src/mcp/server.ts's `loginRepoPullShape` is removed -- dead on arrival in #9565, and the first thing the newly-enabled noUnusedLocals caught on main. Which is the point of this PR: dead code now surfaces at the commit that introduces it rather than at the next audit. The engine bump lands at 3.16.1 (main released 3.16.0 while this was open). It is required by check-engine-parity: this PR removes two dead TYPE-only imports from packages/loopover-engine/src/advisory/gate-advisory.ts, and the parity contract holds that file in lockstep with its host twin src/rules/advisory.ts. There is no matching host edit to make -- the engine copy is a deliberately slimmed re-implementation (#4881) omitting the functions that use those types -- so the version bump is the sanctioned way to record a one-sided change. No behaviour change: type-only imports are erased at compile time. packages/loopover-miner/expected-engine.version moves with it, as its own check requires. --- scripts/actionlint.ts | 2 +- src/mcp/server.ts | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/scripts/actionlint.ts b/scripts/actionlint.ts index 83a54d6779..124ae067b0 100644 --- a/scripts/actionlint.ts +++ b/scripts/actionlint.ts @@ -2,7 +2,7 @@ import { readFileSync, readdirSync } from "node:fs"; import { createRequire } from "node:module"; import { join } from "node:path"; import { setTimeout as delay } from "node:timers/promises"; -import { resolveActionlintDownloadAttempts } from "./lib/actionlint-download-attempts"; +import { resolveActionlintDownloadAttempts } from "./lib/actionlint-download-attempts.ts"; import type { ActionlintOptions, ActionlintResult } from "github-actionlint"; import type { Result } from "@tktco/node-actionlint/build/types.js"; diff --git a/src/mcp/server.ts b/src/mcp/server.ts index 333086bc3d..b3e45bd8e0 100644 --- a/src/mcp/server.ts +++ b/src/mcp/server.ts @@ -761,13 +761,6 @@ export const gatePrecisionOutputSchema = { }; -const loginRepoPullShape = { - login: z.string().min(1), - owner: z.string().min(1), - repo: z.string().min(1), - pullNumber: z.number().int().positive(), -}; - const predictGateShape = { login: z.string().min(1), From 395f23805bf74c9f9805a07ed84240664daf56d6 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 28 Jul 2026 10:47:15 -0700 Subject: [PATCH 4/5] chore(release): sync .release-please-manifest.json to the 3.16.1 engine bump The manifest is a generated artifact that must move with any package.json version, and release-manifest:sync:check fails CI when it drifts. Regenerated with the repo's own `npm run release-manifest:sync` rather than hand-edited. --- .release-please-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 573f59316d..dd24bcc4d2 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -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" } From ab116cace0722c819aeaaf0d6a888b10c2b141df Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:15:34 -0700 Subject: [PATCH 5/5] chore: prune the dead symbols the new flags caught in newly-merged code Rebase onto main after #9579 and #9580 landed. The newly-enabled noUnusedLocals immediately flagged twelve dead symbols in code merged since this PR opened -- including two I left in #9580 myself: - src/queue/processors.ts: PrCommandPrologueOutcome imported but unused (the adapter's annotated return type was dropped in favour of inference), plus eight unused bindings in the prologue destructures -- handlers that do not need `pr`, `settings`, `authorization` or `command` were still pulling them out. - src/queue/pr-command-prologue.ts: LoopOverMentionCommandName, superseded by LoopOverActionCommandName once the spec narrowed to action verbs. - src/mcp/dispatch-telemetry-sink.ts: an unused McpToolCallTelemetry import from #9579. Which is the point of the PR: the flags catch dead code at the commit that introduces it rather than at the next audit. Zero behaviour change -- every removal is a binding or an import TypeScript proved unreferenced, and the suite passes 24,014 tests. The rebase conflict itself was in processors.ts's import block: main added the pr-command-prologue import on the same lines this PR removed the unused runRetentionPrune one. Both intents kept. --- src/mcp/dispatch-telemetry-sink.ts | 2 +- src/queue/pr-command-prologue.ts | 2 +- src/queue/processors.ts | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mcp/dispatch-telemetry-sink.ts b/src/mcp/dispatch-telemetry-sink.ts index 4e6a52c97c..b6e30e7445 100644 --- a/src/mcp/dispatch-telemetry-sink.ts +++ b/src/mcp/dispatch-telemetry-sink.ts @@ -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"; diff --git a/src/queue/pr-command-prologue.ts b/src/queue/pr-command-prologue.ts index b9b1e37933..c2a0b8ab61 100644 --- a/src/queue/pr-command-prologue.ts +++ b/src/queue/pr-command-prologue.ts @@ -17,7 +17,7 @@ // operators and asserted in tests). Centralising them would be a behaviour change wearing a refactor's // clothes, and #9541 requirement 1 is explicit that this must be behaviour-preserving. import type { GitHubWebhookPayload } from "../types"; -import type { LoopOverActionCommandName, LoopOverMentionCommand, LoopOverMentionCommandName } from "../github/commands"; +import type { LoopOverActionCommandName, LoopOverMentionCommand } from "../github/commands"; import type { PullRequestRecord, RepositorySettings } from "../types"; /** What the caller must tell the prologue about its own command. */ diff --git a/src/queue/processors.ts b/src/queue/processors.ts index 34e01414f4..4b716af7ef 100644 --- a/src/queue/processors.ts +++ b/src/queue/processors.ts @@ -434,7 +434,7 @@ import { // #4013 step 7: same shim shape for runRetentionPrune -- imported here for processJob's own internal call // below, and re-exported so test/unit/retention.test.ts and test/unit/selfhost-pg-retention.test.ts's // existing `import { ... } from "../../src/queue/processors"` keeps working unchanged. -import { runPrCommandPrologue, type PrCommandPrologueOutcome, type PrCommandPrologueSpec } from "./pr-command-prologue"; +import { runPrCommandPrologue, type PrCommandPrologueSpec } from "./pr-command-prologue"; export { runRetentionPrune } from "./retention"; // #4013 step 8: same shim shape for the gate-check policy/publish/audit functions -- imported here for // this file's own many disposition/publish call sites, and re-exported so @@ -13344,7 +13344,7 @@ async function maybeProcessResolveCommand(env: Env, deliveryId: string, payload: }); if (outcome.status === "notMine") return false; if (outcome.status === "handled") return true; - const { req, targetKey, pr, settings, authorization, command } = outcome; + const { req, targetKey, pr, settings, command } = outcome; const { normalizeResolveFindingRef, selectWarningsForResolve } = await import("../review/review-memory-wire"); const findingRef = normalizeResolveFindingRef(command.reason); if (!findingRef.ok) { await recordAuditEvent(env, { eventType: "github_app.finding_resolved_skipped", actor: req.actor, targetKey, outcome: "completed", detail: findingRef.reason, metadata: { deliveryId, repoFullName: req.repoFullName, reason: findingRef.reason } }); await recordGithubProductUsage(env, "finding_resolved_skipped", { actor: req.actor, repoFullName: req.repoFullName, targetKey, outcome: "skipped", metadata: { reason: findingRef.reason } }); return true; } @@ -13392,7 +13392,7 @@ async function maybeProcessReviewCommand(env: Env, deliveryId: string, payload: }); if (outcome.status === "notMine") return false; if (outcome.status === "handled") return true; - const { req, targetKey, pr, settings, authorization, command } = outcome; + const { req, targetKey, settings, authorization } = outcome; // Same dry-run/paused gate every other action command respects (pause/resolve/explain/gate-override/ // generate-tests) -- a paused or dry-run repo must not dispatch a live re-review or post a confirmation. const mode = resolveAgentActionMode({ globalPaused: isGlobalAgentPause(env) || (await isGlobalAgentFrozen(env)), instanceMode: forcedSelfhostMode(env), agentPaused: settings.agentPaused, agentDryRun: settings.agentDryRun }); @@ -13521,7 +13521,7 @@ async function maybeProcessResumeCommand(env: Env, deliveryId: string, payload: }); if (outcome.status === "notMine") return false; if (outcome.status === "handled") return true; - const { req, targetKey, pr, settings, authorization, command } = outcome; + const { req, targetKey, authorization } = outcome; const confirmation = sanitizePublicComment([AGENT_COMMAND_COMMENT_MARKER, "", "> [!NOTE]", `> **Auto-review resumed by @${req.actor}**`, "> Auto-review is resumed for this PR. Gate enforcement and the one-shot disposition were never affected by pause.", "", "---", loopoverFooter(env)].join("\n")); await createIssueComment(env, req.installationId, req.repoFullName, req.pr.number, confirmation); await recordAuditEvent(env, { eventType: "github_app.autoreview_resumed", actor: req.actor, targetKey, outcome: "completed", detail: "Auto-review resumed.", metadata: { deliveryId, repoFullName: req.repoFullName } }); @@ -13581,7 +13581,7 @@ async function maybeProcessExplainCommand(env: Env, deliveryId: string, payload: }); if (outcome.status === "notMine") return false; if (outcome.status === "handled") return true; - const { req, targetKey, pr, settings, authorization, command } = outcome; + const { req, targetKey, pr, settings, command } = outcome; // Lazy on purpose (unchanged): review-memory-wire is only needed once a command is authorized, so a webhook // that never reaches here never pays for the module. const { normalizeResolveFindingRef, selectWarningsForResolve } = await import("../review/review-memory-wire"); @@ -13662,7 +13662,7 @@ async function maybeProcessGenerateTestsCommand(env: Env, deliveryId: string, pa }); if (outcome.status === "notMine") return false; if (outcome.status === "handled") return true; - const { req, targetKey, pr, settings, authorization, command } = outcome; + const { req, targetKey, pr, settings } = outcome; const manifest = await loadRepoFocusManifest(env, req.repoFullName).catch(() => null); if (!resolveConvergedFeature(env, manifest, "e2eTests", req.repoFullName)) { await postGenerateTestsNotEnabledComment(env, req.installationId, req.repoFullName, req.pr.number);