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
17 changes: 13 additions & 4 deletions src/api/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -743,11 +743,16 @@
.strict();

const digestSubscriptionSchema = z
.object({

Check notice on line 746 in src/api/routes.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 746 in src/api/routes.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

PR author has maintainer association

This PR appears to come from a maintainer-associated account.
email: z.string().email().max(320),
})
.strict();

function contributorOpenIssueCount(issues: Array<{ repoFullName: string; state: string }>, repoFullName: string): number {
const targetRepo = repoFullName.toLowerCase();
return issues.filter((issue) => issue.repoFullName.toLowerCase() === targetRepo && issue.state === "open").length;
}

export function createApp() {
const app = new Hono<AppBindings>();
app.use("*", async (c, next) => {
Expand Down Expand Up @@ -1595,13 +1600,15 @@
const unauthorized = await requireContributorAccess(c, parsed.data.contributorLogin);
if (unauthorized) return unauthorized;
}
const [repo, snapshot, evidence] = await Promise.all([
const [repo, snapshot, evidence, contributorIssues] = await Promise.all([
getRepository(c.env, parsed.data.repoFullName),
getOrCreateScoringModelSnapshot(c.env),
parsed.data.contributorLogin ? getContributorEvidence(c.env, parsed.data.contributorLogin) : Promise.resolve(null),
parsed.data.contributorLogin ? listContributorIssues(c.env, parsed.data.contributorLogin) : Promise.resolve([]),
]);
const openIssueCount = contributorOpenIssueCount(contributorIssues, parsed.data.repoFullName);
// Time-decay (#703) is an owner-gated global, injected server-side (not caller-controllable).
const input = { ...parsed.data, applyTimeDecay: isTimeDecayEnabled(c.env) };
const input = { ...parsed.data, openIssueCount, applyTimeDecay: isTimeDecayEnabled(c.env) };
const result = buildScorePreview({ input, repo, snapshot, contributorEvidence: evidence });
const record = makeScorePreviewRecord(input, snapshot, result);
await persistScorePreview(c.env, record);
Expand All @@ -1615,13 +1622,15 @@
if (!parsed.data.contributorLogin) return c.json({ error: "contributor_login_required" }, 400);
const unauthorized = await requireContributorAccess(c, parsed.data.contributorLogin);
if (unauthorized) return unauthorized;
const [repo, snapshot, evidence] = await Promise.all([
const [repo, snapshot, evidence, contributorIssues] = await Promise.all([
getRepository(c.env, parsed.data.repoFullName),
getOrCreateScoringModelSnapshot(c.env),
getContributorEvidence(c.env, parsed.data.contributorLogin),
listContributorIssues(c.env, parsed.data.contributorLogin),
]);
const openIssueCount = contributorOpenIssueCount(contributorIssues, parsed.data.repoFullName);
// Time-decay (#703) is an owner-gated global, injected server-side (not caller-controllable).
const input = { ...parsed.data, applyTimeDecay: isTimeDecayEnabled(c.env) };
const input = { ...parsed.data, openIssueCount, applyTimeDecay: isTimeDecayEnabled(c.env) };
const preview = buildScorePreview({ input, repo, snapshot, contributorEvidence: evidence });
return c.json(explainScoreBreakdown(preview));
});
Expand Down
11 changes: 9 additions & 2 deletions src/mcp/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,14 @@
const agentPlanShape = {
login: z.string().min(1),
objective: z.string().min(1).max(500).optional(),
repoFullName: z.string().min(3).optional(),

Check notice on line 513 in src/mcp/server.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 513 in src/mcp/server.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

PR author has maintainer association

This PR appears to come from a maintainer-associated account.
};

function contributorOpenIssueCount(issues: Array<{ repoFullName: string; state: string }>, repoFullName: string): number {
const targetRepo = repoFullName.toLowerCase();
return issues.filter((issue) => issue.repoFullName.toLowerCase() === targetRepo && issue.state === "open").length;
}

const linkedIssueContextShape = {
status: z.enum(["raw", "plausible", "validated", "invalid", "unavailable"]).optional(),
source: z.enum(["user_supplied", "official_mirror", "github_cache", "issue_quality", "missing"]).optional(),
Expand Down Expand Up @@ -2133,13 +2138,15 @@
private async previewScore(input: z.infer<z.ZodObject<typeof scorePreviewShape>>): Promise<ToolPayload> {
if (input.contributorLogin) this.requireContributorAccess(input.contributorLogin);
await this.requireRepoAccess(input.repoFullName);
const [repo, snapshot, evidence] = await Promise.all([
const [repo, snapshot, evidence, contributorIssues] = await Promise.all([
getRepository(this.env, input.repoFullName),
getOrCreateScoringModelSnapshot(this.env),
input.contributorLogin ? getContributorEvidence(this.env, input.contributorLogin) : Promise.resolve(null),
input.contributorLogin ? listContributorIssues(this.env, input.contributorLogin) : Promise.resolve([]),
]);
const openIssueCount = contributorOpenIssueCount(contributorIssues, input.repoFullName);
// Time-decay (#703) is an owner-gated global, injected server-side (not caller-controllable).
const scoreInput = { ...input, applyTimeDecay: isTimeDecayEnabled(this.env) };
const scoreInput = { ...input, openIssueCount, applyTimeDecay: isTimeDecayEnabled(this.env) };
const result = buildScorePreview({ input: scoreInput, repo, snapshot, contributorEvidence: evidence });
return {
summary: `Private Gittensory scoring preview for ${input.repoFullName}.`,
Expand Down
1 change: 1 addition & 0 deletions src/signals/local-branch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,10 @@
sourceTokenScore: scorer?.sourceTokenScore ?? Math.max(0, sourceLineCount),
totalTokenScore: scorer?.totalTokenScore ?? Math.max(0, args.changedLineCount),
sourceLines: scorer?.sourceLines ?? Math.max(1, sourceLineCount || args.changedLineCount || 1),
testTokenScore: scorer?.testTokenScore ?? testLineCount,

Check notice on line 472 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 472 in src/signals/local-branch.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

PR author has maintainer association

This PR appears to come from a maintainer-associated account.
nonCodeTokenScore: scorer?.nonCodeTokenScore ?? nonCodeLineCount,
openPrCount: args.outcomeHistory.totals.openPullRequests,
openIssueCount: args.repoOutcome?.openIssues ?? args.outcomeHistory.totals.openIssues,
credibility: args.repoOutcome?.credibility ?? args.outcomeHistory.totals.credibility,
metadataOnly: scorer?.mode !== "gittensor_root" && scorer?.mode !== "external_command",
pendingMergedPrCount: args.input.pendingMergedPrCount,
Expand Down
2 changes: 2 additions & 0 deletions src/signals/reward-risk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,10 @@
issues: args.issues,
pullRequests: args.pullRequests,
}).recommendation;

Check notice on line 182 in src/signals/reward-risk.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 182 in src/signals/reward-risk.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

PR author has maintainer association

This PR appears to come from a maintainer-associated account.
const labels = bestFitLabels(args.repo);
const currentOpenPrCount = nonNegative(args.outcomeHistory.totals.openPullRequests);
const currentOpenIssueCount = nonNegative(repoOutcome?.openIssues ?? args.outcomeHistory.totals.openIssues);
/* v8 ignore next -- Credibility fallback order protects sparse private snapshots; behavior is covered through scoring profile tests. */
const credibility = repoOutcome?.credibility && repoOutcome.credibility > 0 ? repoOutcome.credibility : args.scoringProfile?.evidence.credibilityAssumption ?? args.outcomeHistory.totals.credibility ?? 0.8;
const commonPreviewInput = {
Expand All @@ -198,6 +199,7 @@
credibility,
metadataOnly: true,
duplicateRiskCount: collisions.summary.highRiskCount,
openIssueCount: currentOpenIssueCount,
};
const currentPreview = buildScorePreview({
input: { ...commonPreviewInput, openPrCount: currentOpenPrCount },
Expand Down
28 changes: 28 additions & 0 deletions test/unit/local-branch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,37 @@
});

// The duplicate_risk reducer was dead before this fix: duplicateRiskCount had no producer.
expect(analysis.scorePreview.blockedBy).toEqual(expect.arrayContaining([expect.objectContaining({ code: "duplicate_risk" })]));

Check notice on line 94 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 94 in test/unit/local-branch.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

PR author has maintainer association

This PR appears to come from a maintainer-associated account.
});

it("applies the open-issue spam gate from trusted outcome history", () => {
const issueHeavyHistory: ContributorOutcomeHistory = {
...outcomeHistory,
totals: { ...outcomeHistory.totals, issues: 99, openIssues: 99 },
repoOutcomes: [{ ...outcomeHistory.repoOutcomes[0]!, issues: 99, openIssues: 99 }],
};
const analysis = buildLocalBranchAnalysis({
input: {
login: "oktofeesh1",
repoFullName: repo.fullName,
labels: ["enhancement"],
changedFiles: [{ path: "src/cache.ts", additions: 42, deletions: 4, status: "modified" }],
localScorer: { mode: "external_command", sourceTokenScore: 48, totalTokenScore: 80, sourceLines: 46 },
},
repo,
issues: [],
pullRequests: [],
profile,
outcomeHistory: issueHeavyHistory,
scoringSnapshot,
scoringProfile,
});

expect(analysis.scorePreview.gates.openIssueCount).toBe(99);
expect(analysis.scorePreview.scoreEstimate.openIssueMultiplier).toBe(0);
expect(analysis.scorePreview.blockedBy).toEqual(expect.arrayContaining([expect.objectContaining({ code: "open_issue_threshold" })]));
});

it("bounds local scorer warnings before adding local findings", () => {
const analysis = buildLocalBranchAnalysis({
input: {
Expand Down
Loading