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
8 changes: 5 additions & 3 deletions src/review/maintainer-recap-wire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ export function shouldFireMaintainerRecap(
}

/** The repos this recap scans. Mirrors ops-wire.ts's opsScanRepos / pr-reconciliation.ts's watchedRepos: prefer
* agent-configured repos when any opted in (the acting-autonomy surface), else fall back to every registered
* repo so the digest still reports before the agent is enabled anywhere. */
* agent-configured repos when any opted in (the acting-autonomy surface), else fall back to every installed
* repo so the digest still reports before the agent is enabled anywhere. The maintainer recap digest reports
* on PR/issue backlog and review activity for repos the agent runs on -- core review-ops, unrelated to
* gittensor-subnet registry membership, so `isInstalled` (#5016), not `isRegistered`. */
async function recapScanRepos(env: Env): Promise<string[]> {
const repos = (await listRepositories(env)).filter((repo) => repo.isRegistered);
const repos = (await listRepositories(env)).filter((repo) => repo.isInstalled);
const configured: string[] = [];
for (const repo of repos) {
try {
Expand Down
11 changes: 7 additions & 4 deletions src/review/ops-wire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,15 @@ export function worstAnomaly(anomalies: string[]): { line: string; severity: Pag

// ── Cron alerts: scan gittensory's outcome data, emit a structured log on drift (flag-gated by the caller) ──

/** The registered repos to scan. Scoped to REGISTERED repos (the ones gittensory actually tracks outcomes
* for) — same `isRegistered` filter the other scheduled fan-outs use. */
/** The installed repos to scan. Mirrors fanOutAgentRegateSweepJobs's own repo population (#5016): outcome
* telemetry (gate precision, slop calibration, review-burst detection) is core review-quality monitoring for
* any repo the review agent actually runs on, unrelated to gittensor-subnet registry membership -- NOT
* `isRegistered`, which this used to (wrongly) match, despite this doc comment's own inner installationId
* guard below already assuming installation, not registration, is what matters. */
async function opsScanRepos(env: Env): Promise<string[]> {
const repos = (await listRepositories(env)).filter((repo) => repo.isRegistered);
const repos = (await listRepositories(env)).filter((repo) => repo.isInstalled);
// Prefer agent-configured repos when any opted in (the acting-autonomy surface, like the regate sweep); fall
// back to every registered repo so outcome telemetry is still scanned before the agent is enabled anywhere.
// back to every installed repo so outcome telemetry is still scanned before the agent is enabled anywhere.
const configured: string[] = [];
for (const repo of repos) {
try {
Expand Down
8 changes: 5 additions & 3 deletions src/review/selftune-wire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ async function buildEvalRow(env: Env, repoFullName: string): Promise<GateEvalRow
return evalRowFromCalibration(repoFullName, calibration.recommendations.positive, calibration.recommendations.negative);
}

/** The registered, agent-configured repos to tune over — SAME scoping the ops scan + regate sweep use (only
* repos that opt into the acting-autonomy surface). A repo whose settings blip is skipped, never aborts.
/** The installed, agent-configured repos to tune over — SAME scoping the ops scan + regate sweep use (only
* repos that opt into the acting-autonomy surface). Self-tune calibrates the review gate's own confidence
* floor from outcome data, core review-quality machinery unrelated to gittensor-subnet registry membership,
* so this is `isInstalled` (#5016), not `isRegistered`. A repo whose settings blip is skipped, never aborts.
*
* Per-repo opt-out (#4104): unlike rag/reputation/grounding, selftune has no `LOOPOVER_REVIEW_REPOS`
* allowlist to fall back to — every agent-configured repo is already IN by default once the global flag is
Expand All @@ -113,7 +115,7 @@ async function buildEvalRow(env: Env, repoFullName: string): Promise<GateEvalRow
* safety boundary this config key must not touch. Unset (the default) changes nothing. A manifest-load error
* fails open (repo stays included), matching the existing settings-blip fail-safe below. */
async function selfTuneRepos(env: Env): Promise<string[]> {
const repos = (await listRepositories(env)).filter((repo) => repo.isRegistered);
const repos = (await listRepositories(env)).filter((repo) => repo.isInstalled);
const configured: string[] = [];
for (const repo of repos) {
try {
Expand Down
26 changes: 26 additions & 0 deletions test/unit/maintainer-recap-wire.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,32 @@ describe("runMaintainerRecapJob — cross-repo digest (#1963, #2248)", () => {
expect(posted).toHaveLength(1);
});

it("#5016: includes an installed-but-not-subnet-registered repo in the digest (PR/issue backlog reporting is core review-ops, not subnet-gated)", async () => {
const env = createTestEnv({ DISCORD_WEBHOOK_URL: HOOK });
await env.DB.prepare("INSERT INTO repositories (full_name, owner, name, is_installed, is_registered) VALUES (?, ?, ?, 1, 0)")
.bind("acme/installed-not-registered", "acme", "installed-not-registered")
.run();
await seedMergedPr(env, "acme/installed-not-registered", 1);
stubDiscordFetch();

const { report } = ranRecap(await runMaintainerRecapJob(env));

expect(report.repos.map((r) => r.repoFullName)).toContain("acme/installed-not-registered");
});

it("#5016: excludes a subnet-registered-but-not-installed repo from the digest", async () => {
const env = createTestEnv({ DISCORD_WEBHOOK_URL: HOOK });
await env.DB.prepare("INSERT INTO repositories (full_name, owner, name, is_installed, is_registered) VALUES (?, ?, ?, 0, 1)")
.bind("acme/registered-not-installed", "acme", "registered-not-installed")
.run();
await seedMergedPr(env, "acme/registered-not-installed", 1);
stubDiscordFetch();

const { report } = ranRecap(await runMaintainerRecapJob(env));

expect(report.repos.map((r) => r.repoFullName)).not.toContain("acme/registered-not-installed");
});

it("keeps miner cohort diagnostics out of the scheduled external recap", async () => {
const env = createTestEnv({ DISCORD_WEBHOOK_URL: HOOK });
await seedRegisteredRepo(env, "owner/alpha");
Expand Down
24 changes: 24 additions & 0 deletions test/unit/ops-wire.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,30 @@ describe("runOpsAlerts — cron path over gittensory's outcome data", () => {
expect(found["owner/no-install"]).toBeUndefined();
});

it("#5016: scans an installed-but-not-subnet-registered repo (outcome monitoring is core review-ops, not subnet-gated)", async () => {
const env = createTestEnv();
await env.DB.prepare("INSERT INTO repositories (full_name, owner, name, is_installed, is_registered) VALUES (?, ?, ?, 1, 0)")
.bind("acme/installed-not-registered", "acme", "installed-not-registered")
.run();
await seedGateFalsePositiveAnomaly(env, "acme/installed-not-registered");

const found = await runOpsAlerts(env);

expect(found["acme/installed-not-registered"]?.some((a) => /gate false-positive spike/.test(a))).toBe(true);
});

it("#5016: excludes a subnet-registered-but-not-installed repo from the ops scan", async () => {
const env = createTestEnv();
await env.DB.prepare("INSERT INTO repositories (full_name, owner, name, is_installed, is_registered) VALUES (?, ?, ?, 0, 1)")
.bind("acme/registered-not-installed", "acme", "registered-not-installed")
.run();
await seedGateFalsePositiveAnomaly(env, "acme/registered-not-installed");

const found = await runOpsAlerts(env);

expect(found["acme/registered-not-installed"]).toBeUndefined();
});

it("detects and reports a review burst end-to-end (a PR published far more review surfaces than normal in the window)", async () => {
setSelfHostedMetricsMode(true); // keep the repo label so the counter assertion can target the exact series
const env = createTestEnv();
Expand Down
34 changes: 34 additions & 0 deletions test/unit/selftune-wiring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,40 @@ describe("selfTuneRepos — per-repo review.selftune FORCE-OFF (#4104)", () => {
expect(await loadShadowOverride(env as never, `${owner}/${name}`)).toBeNull();
});

it("#5016: tunes an installed-but-not-subnet-registered repo (gate self-calibration is core review-ops, not subnet-gated)", async () => {
const owner = "acme";
const name = "installed-not-registered";
const env = createTestEnv({ LOOPOVER_REVIEW_SELFTUNE: "true" });
await env.DB.prepare("INSERT INTO repositories (full_name, owner, name, is_installed, is_registered, installation_id) VALUES (?, ?, ?, 1, 0, ?)")
.bind(`${owner}/${name}`, owner, name, 9601)
.run();
await env.DB.prepare("INSERT INTO repository_settings (repo_full_name, autonomy_json) VALUES (?, ?)")
.bind(`${owner}/${name}`, ACTING_AUTONOMY)
.run();
await seedRecommendationOutcomes(env, `${owner}/${name}`, 5, 10);

await runSelfTune(env);

expect((await loadShadowOverride(env as never, `${owner}/${name}`))?.override.confidenceFloor).toBeGreaterThan(0);
});

it("#5016: excludes a subnet-registered-but-not-installed repo from the tuning pass", async () => {
const owner = "acme";
const name = "registered-not-installed";
const env = createTestEnv({ LOOPOVER_REVIEW_SELFTUNE: "true" });
await env.DB.prepare("INSERT INTO repositories (full_name, owner, name, is_installed, is_registered, installation_id) VALUES (?, ?, ?, 0, 1, ?)")
.bind(`${owner}/${name}`, owner, name, 9602)
.run();
await env.DB.prepare("INSERT INTO repository_settings (repo_full_name, autonomy_json) VALUES (?, ?)")
.bind(`${owner}/${name}`, ACTING_AUTONOMY)
.run();
await seedRecommendationOutcomes(env, `${owner}/${name}`, 5, 10);

await runSelfTune(env);

expect(await loadShadowOverride(env as never, `${owner}/${name}`)).toBeNull();
});

it("unset review.selftune (the default) does not change today's behavior — an agent-configured repo still tunes normally", async () => {
const env = createTestEnv({ LOOPOVER_REVIEW_SELFTUNE: "true" });
await seedRegisteredRepo(env, "owner/repo", ACTING_AUTONOMY);
Expand Down