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
6 changes: 6 additions & 0 deletions apps/gittensory-ui/public/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -2217,6 +2217,12 @@
}
}
},
"evidenceGraph": {
"type": "object",
"additionalProperties": {
"nullable": true
}
},
"dataQuality": {
"type": "object",
"additionalProperties": {
Expand Down
1 change: 1 addition & 0 deletions src/db/repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ const MAX_SIGNAL_FRESHNESS_TARGETS = 200;
const MAX_SIGNAL_FRESHNESS_TARGET_KEY_CHARS = 256;
const FRESHNESS_SIGNAL_TYPES = [
"contributor-decision-pack",
"contributor-evidence-graph",
"contributor-intake-health",
"contributor-outcome-history",
"contributor-strategy",
Expand Down
1 change: 1 addition & 0 deletions src/openapi/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,7 @@ export const ContributorDecisionPackSchema = z
avoidRepos: z.array(z.record(z.unknown())),
maintainerLaneRepos: z.array(z.record(z.unknown())),
scoreBlockers: z.array(z.record(z.unknown())),
evidenceGraph: z.record(z.unknown()).optional(),
dataQuality: z.record(z.unknown()),
summary: z.string(),
nextActions: z.array(z.string()),
Expand Down
52 changes: 52 additions & 0 deletions src/queue/processors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
listPullRequests,
listRecentMergedPullRequests,
listRepoLabels,
listRepoPullRequestFiles,
listRepoSyncStates,
listRepoSyncSegments,
listRepositories,
Expand Down Expand Up @@ -73,6 +74,11 @@ import { refreshRegistry } from "../registry/sync";
import { buildIssueAdvisory, buildPullRequestAdvisory } from "../rules/advisory";
import { getOrCreateScoringModelSnapshot, refreshScoringModelSnapshot } from "../scoring/model";
import { buildAndPersistContributorDecisionPack, loadDecisionPackSharedInputs } from "../services/decision-pack";
import {
buildContributorEvidenceGraph,
CONTRIBUTOR_EVIDENCE_GRAPH_SIGNAL,
evidenceGraphTouchedRepoFullNames,
} from "../services/contributor-evidence-graph";
import { executeAgentRun, explainBlockersWithAgent, planNextWork, preflightBranchWithAgent, preparePrPacketWithAgent } from "../services/agent-orchestrator";
import { isAuthorizedGitHubSessionLogin } from "../auth/security";
import { loadIssueQualityReportMap } from "../services/issue-quality";
Expand Down Expand Up @@ -108,6 +114,7 @@ import {
buildPublicCommentSignalBundle,
buildPublicPrIntelligenceComment,
buildQueueHealth,
buildRoleContext,
detectGittensorContributor,
} from "../signals/engine";
import { rewritePublicPrIntelligenceComment } from "../services/ai-summaries";
Expand Down Expand Up @@ -348,10 +355,47 @@ async function buildContributorEvidence(env: Env, login?: string): Promise<void>
]);
const repoStats = authoritativeContributorRepoStats(gittensorSnapshot, cachedRepoStats);
const profile = buildContributorProfile(contributorLogin, github, contributorPullRequests, contributorIssues, repoStats, gittensorSnapshot);
const pullRequestFiles = (
await Promise.all(
evidenceGraphTouchedRepoFullNames({
login: contributorLogin,
profile,
pullRequests: contributorPullRequests,
issues: contributorIssues,
repoStats,
repositories,
}).map((repoFullName) => listRepoPullRequestFiles(env, repoFullName)),
)
).flat();
const fit = buildContributorFit(profile, repositories, allIssues, allPullRequests, syncStates, repoStats, allBounties, issueQualityByRepo);
const scoringProfile = buildContributorScoringProfile({ login: contributorLogin, fit, scoringSnapshot: snapshot });
const outcomeHistory = buildContributorOutcomeHistory({ login: contributorLogin, profile, repositories, pullRequests: allPullRequests, issues: allIssues, repoStats, cachedRepoStats });
const strategy = buildContributorStrategy({ login: contributorLogin, fit, scoringProfile, scoringSnapshot: snapshot, outcomeHistory });
const roleContexts = repositories
.filter((repo) => repo.isRegistered)
.map((repo) =>
buildRoleContext({
login: contributorLogin,
repo,
repoFullName: repo.fullName,
pullRequests: contributorPullRequests,
issues: contributorIssues,
profile,
}),
);
const evidenceGraph = buildContributorEvidenceGraph({
login: contributorLogin,
profile,
outcomeHistory,
roleContexts,
repositories,
pullRequests: contributorPullRequests,
issues: contributorIssues,
repoStats,
syncStates,
pullRequestFiles,
gittensorSnapshot,
});
const evidence: ContributorEvidenceRecord = {
login: contributorLogin,
generatedAt: scoringProfile.generatedAt,
Expand All @@ -364,6 +408,7 @@ async function buildContributorEvidence(env: Env, login?: string): Promise<void>
issueDiscoveryReports: scoringProfile.evidence.issueDiscoveryReports,
languageMatches: scoringProfile.evidence.languageMatches,
credibilityAssumption: scoringProfile.evidence.credibilityAssumption,
evidenceGraph: evidenceGraph as unknown as JsonValue,
},
};
await upsertContributorEvidence(env, evidence);
Expand All @@ -387,6 +432,13 @@ async function buildContributorEvidence(env: Env, login?: string): Promise<void>
payload: strategy as unknown as Record<string, JsonValue>,
generatedAt: strategy.generatedAt,
});
await persistSignalSnapshot(env, {
id: crypto.randomUUID(),
signalType: CONTRIBUTOR_EVIDENCE_GRAPH_SIGNAL,
targetKey: contributorLogin,
payload: evidenceGraph as unknown as Record<string, JsonValue>,
generatedAt: evidenceGraph.generatedAt,
});
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/services/agent-orchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,15 @@ function contextSnapshotFromPack(runId: string, pack: ContributorDecisionPack, d
login: pack.login,
source: pack.source,
selectedRepos: decisions.map((decision) => decision.repoFullName),
evidenceGraph: (pack.evidenceGraph
? {
version: pack.evidenceGraph.version,
generatedAt: pack.evidenceGraph.generatedAt,
totals: pack.evidenceGraph.totals,
sources: pack.evidenceGraph.sources,
selectedRepos: pack.evidenceGraph.repos.filter((repo) => decisions.some((decision) => decision.repoFullName.toLowerCase() === repo.repoFullName.toLowerCase())),
}
: null) as unknown as JsonValue,
dataQuality: pack.dataQuality as unknown as JsonValue,
openPrMonitor: (pack.openPrMonitor ?? null) as unknown as JsonValue,
},
Expand Down
Loading