Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/signals/local-branch.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { BranchEligibilityInput, BranchEligibilityResult, LinkedIssueMultiplierContext, ScorePreviewInput, ScorePreviewResult } from "../scoring/preview";
import { buildScorePreview } from "../scoring/preview";
import type { GittensorContributorSnapshot } from "../gittensor/api";
import type { BountyRecord, CheckSummaryRecord, IssueRecord, PullRequestRecord, RecentMergedPullRequestRecord, RepositoryRecord, ScoringModelSnapshotRecord } from "../types";

Check notice on line 4 in src/signals/local-branch.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.

Check notice on line 4 in src/signals/local-branch.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Open PR queue is busy

This repo has a busy open PR queue in the local Gittensory cache.
import { nowIso } from "../utils/json";
import {
buildCollisionReport,
buildLaneAdvice,
buildLocalDiffPreflightResult,
buildQueueHealth,
buildRepoFitRecommendation,
buildRoleContext,
type ContributorOutcomeHistory,
Expand All @@ -23,6 +25,7 @@
import { deriveEligibilityPlan } from "../services/eligibility-plan";
import { scenarioInputFromLocalBranchMetadata } from "../scenarios/input-model";
import { renderPublicScenarioSummary, type PublicScenarioSummary, type ScenarioSummaryInput } from "../scenarios/scenario-summary";
import { simulateOpenPrPressure } from "../services/open-pr-pressure-scenarios";

export type LocalBranchChangedFile = {
path: string;
Expand Down Expand Up @@ -366,13 +369,26 @@
classified: [],
}
: undefined;
// Open-PR pressure strategy options (#348): the scenario summary renderer fills its strategy
// `options` (open new work / wait / clean up first) and headline from this simulation. Without
// passing it, scenarioSummary.options was always empty and the guidance never reached the miner.
const queuePressureSimulation = simulateOpenPrPressure({
repoFullName: args.input.repoFullName,
generatedAt: nowIso(),
queueHealth: buildQueueHealth(args.repo, args.issues, args.pullRequests, buildCollisionReport(args.input.repoFullName, args.issues, args.pullRequests)),
roleContext,
contributorOpenPrCount: (args.contributorPullRequests ?? args.pullRequests).filter(
(pr) => pr.state === "open" && (pr.authorLogin ?? "").toLowerCase() === args.input.login.toLowerCase(),
).length,
});
const scenarioSummary = renderPublicScenarioSummary({
repoFullName: args.input.repoFullName,
generatedAt: nowIso(),
eligibilityPlan,
publicBlockers: scorePreview.blockedBy,
scenarioInput: branchScenarioInput,
pendingDetection: pendingDetectionForSummary,
pressureSimulation: queuePressureSimulation,
});
return {
login: args.input.login,
Expand Down
37 changes: 37 additions & 0 deletions test/unit/local-branch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1568,7 +1568,7 @@
pullRequests: [],
profile,
outcomeHistory,
scoringSnapshot,

Check notice on line 1571 in test/unit/local-branch.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.

Check notice on line 1571 in test/unit/local-branch.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Open PR queue is busy

This repo has a busy open PR queue in the local Gittensory cache.
scoringProfile,
});

Expand Down Expand Up @@ -1604,6 +1604,43 @@
expect(analysis.scenarioSummary.dataClassification.facts).toEqual(expect.arrayContaining(["Contributor", "Repository", "Branch"]));
});

it("wires open-PR pressure strategy options into scenarioSummary.options (#348)", () => {
const analysis = buildLocalBranchAnalysis({
input: {
login: "oktofeesh1",
repoFullName: repo.fullName,
changedFiles: [{ path: "src/util.ts", additions: 30, deletions: 2, status: "modified" }],
localScorer: { mode: "external_command", sourceTokenScore: 40, totalTokenScore: 60, sourceLines: 38 },
},
repo,
issues: [{ repoFullName: repo.fullName, number: 9, title: "Improve util", state: "open", labels: [], linkedPrs: [] }],
pullRequests: [
{ repoFullName: repo.fullName, number: 4, title: "WIP util", state: "open", authorLogin: "oktofeesh1", labels: [], linkedIssues: [] },
],
// contributorPullRequests is preferred when present; the authorless PR exercises the null-author
// guard in the own-open-PR count and must not be miscounted as this contributor's work.
contributorPullRequests: [
{ repoFullName: repo.fullName, number: 4, title: "WIP util", state: "open", authorLogin: "oktofeesh1", labels: [], linkedIssues: [] },
{ repoFullName: repo.fullName, number: 5, title: "Authorless", state: "open", authorLogin: null, labels: [], linkedIssues: [] },
],
profile,
outcomeHistory,
scoringSnapshot,
scoringProfile,
});

// Before this fix the renderer never received the pressure simulation, so options was always [].
const options = analysis.scenarioSummary.options;
expect(options.length).toBe(3);
expect(options.map((option) => option.rank)).toEqual([1, 2, 3]);
expect(options.filter((option) => option.recommended)).toHaveLength(1);
expect(options[0]?.recommended).toBe(true);
for (const option of options) {
expect(option.label.length).toBeGreaterThan(0);
expect(option.nextStep.length).toBeGreaterThan(0);
}
});

it("populates scenarioSummary.dataClassification with contributor and repo facts from branch metadata", () => {
const analysis = buildLocalBranchAnalysis({
input: {
Expand Down
Loading