From 2c04f971297f4e9cd2af820f5fb5f0b215df37ee Mon Sep 17 00:00:00 2001 From: kiannidev <156195510+kiannidev@users.noreply.github.com> Date: Thu, 4 Jun 2026 21:30:09 +0200 Subject: [PATCH 1/5] feat(registration): add Gittensory self-dogfood registration pack Compose registration readiness and config recommendations into a private, rerunnable maintainer report for the Gittensory repo with direct-PR-first guidance and actionable readiness areas. Fixes #117 --- apps/gittensory-ui/public/openapi.json | 60 ++++++ src/api/routes.ts | 40 +++- src/openapi/spec.ts | 16 ++ .../self-dogfood-registration-pack.ts | 161 ++++++++++++++ .../self-dogfood-registration-pack.test.ts | 203 ++++++++++++++++++ 5 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 src/services/self-dogfood-registration-pack.ts create mode 100644 test/unit/self-dogfood-registration-pack.test.ts diff --git a/apps/gittensory-ui/public/openapi.json b/apps/gittensory-ui/public/openapi.json index 2697717d..ffd72a4a 100644 --- a/apps/gittensory-ui/public/openapi.json +++ b/apps/gittensory-ui/public/openapi.json @@ -14020,6 +14020,66 @@ } ] } + }, + "/v1/app/self-dogfood/registration-pack": { + "get": { + "responses": { + "200": { + "description": "Private self-dogfood registration pack for the Gittensory repo", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "nullable": true + } + } + } + } + }, + "403": { + "description": "Insufficient role for maintainer-only self-dogfood report" + } + }, + "security": [ + { + "GittensoryBearer": [] + }, + { + "GittensorySessionCookie": [] + } + ] + } + }, + "/v1/repos/{owner}/{repo}/self-dogfood-registration-pack": { + "get": { + "responses": { + "200": { + "description": "Private self-dogfood registration pack when repo matches configured Gittensory target", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "nullable": true + } + } + } + } + }, + "403": { + "description": "Repo is not the configured self-dogfood target" + } + }, + "security": [ + { + "GittensoryBearer": [] + }, + { + "GittensorySessionCookie": [] + } + ] + } } }, "servers": [ diff --git a/src/api/routes.ts b/src/api/routes.ts index 8855b1a6..451c8848 100644 --- a/src/api/routes.ts +++ b/src/api/routes.ts @@ -140,6 +140,7 @@ import { MINIMUM_SUPPORTED_MCP_VERSION, } from "../services/mcp-compatibility"; import { buildOperatorDashboardPayload } from "../services/operator-dashboard"; +import { buildSelfDogfoodRegistrationPack, resolveSelfDogfoodRepoFullName } from "../services/self-dogfood-registration-pack"; import { buildWeeklyValueReport, formatWeeklyValueReportMarkdown, @@ -180,7 +181,12 @@ import { buildLocalBranchAnalysis, findCurrentBranchPullRequest } from "../signa import { MAX_LOCAL_SCORER_WARNING_CHARS, MAX_LOCAL_SCORER_WARNING_COUNT } from "../signals/local-scorer-diagnostics"; import { loadRepoFocusManifest } from "../signals/focus-manifest-loader"; import { buildRepoSettingsPreview, type PublicSurfaceSkipReason } from "../signals/settings-preview"; -import { buildGittensorConfigRecommendation, buildRegistrationReadiness, type InstallationHealthSummary } from "../signals/registration-readiness"; +import { + buildGittensorConfigRecommendation, + buildRegistrationReadiness, + type InstallationHealthSummary, + type RegistrationReadinessReport, +} from "../signals/registration-readiness"; import { fileUpstreamDriftIssues, loadUpstreamStatus, refreshUpstreamDrift, registryHyperparameterDriftWarningsForRepo } from "../upstream/ruleset"; import type { BountyLifecycleEventRecord, @@ -1477,6 +1483,20 @@ export function createApp() { return c.json(await buildGittensorConfigRecommendationResponse(c.env, fullName)); }); + app.get("/v1/app/self-dogfood/registration-pack", async (c) => { + const forbidden = await requireAppRole(c, ["maintainer", "owner", "operator"]); + if (forbidden) return forbidden; + return c.json(await buildSelfDogfoodRegistrationPackResponse(c.env)); + }); + + app.get("/v1/repos/:owner/:repo/self-dogfood-registration-pack", async (c) => { + const fullName = `${c.req.param("owner")}/${c.req.param("repo")}`; + if (fullName.toLowerCase() !== resolveSelfDogfoodRepoFullName(c.env).toLowerCase()) { + return c.json({ error: "self_dogfood_repo_only", repoFullName: resolveSelfDogfoodRepoFullName(c.env) }, 403); + } + return c.json(await buildSelfDogfoodRegistrationPackResponse(c.env)); + }); + app.get("/v1/repos/:owner/:repo/settings", async (c) => { const fullName = `${c.req.param("owner")}/${c.req.param("repo")}`; return c.json(await getRepositorySettings(c.env, fullName)); @@ -2854,6 +2874,24 @@ function stripOwnerPolicyContext(policyRead return publicPolicyReadiness; } +async function buildSelfDogfoodRegistrationPackResponse(env: Env) { + const fullName = resolveSelfDogfoodRepoFullName(env); + const [readinessPayload, recommendationPayload] = await Promise.all([ + buildRegistrationReadinessResponse(env, fullName), + buildGittensorConfigRecommendationResponse(env, fullName), + ]); + const { dataQuality: _readinessQuality, ...registrationReadiness } = readinessPayload; + const { dataQuality: _recommendationQuality, ...gittensorConfigRecommendation } = recommendationPayload; + return { + ...buildSelfDogfoodRegistrationPack({ + repoFullName: fullName, + registrationReadiness: registrationReadiness as RegistrationReadinessReport, + gittensorConfigRecommendation, + }), + dataQuality: _readinessQuality, + }; +} + async function buildGittensorConfigRecommendationResponse(env: Env, fullName: string) { /* v8 ignore start -- Config recommendation route-level shaping over covered signal helpers. */ const intelligence = await buildRepoIntelligenceResponse(env, fullName); diff --git a/src/openapi/spec.ts b/src/openapi/spec.ts index 9b7e109c..76b69967 100644 --- a/src/openapi/spec.ts +++ b/src/openapi/spec.ts @@ -373,6 +373,22 @@ export function buildOpenApiSpec() { 200: { description: "Private Gittensor config recommendation for repo owners", content: { "application/json": { schema: GittensorConfigRecommendationSchema } } }, }, }); + registry.registerPath({ + method: "get", + path: "/v1/app/self-dogfood/registration-pack", + responses: { + 200: { description: "Private self-dogfood registration pack for the Gittensory repo", content: { "application/json": { schema: z.record(z.string(), z.unknown()) } } }, + 403: { description: "Insufficient role for maintainer-only self-dogfood report" }, + }, + }); + registry.registerPath({ + method: "get", + path: "/v1/repos/{owner}/{repo}/self-dogfood-registration-pack", + responses: { + 200: { description: "Private self-dogfood registration pack when repo matches configured Gittensory target", content: { "application/json": { schema: z.record(z.string(), z.unknown()) } } }, + 403: { description: "Repo is not the configured self-dogfood target" }, + }, + }); registry.registerPath({ method: "get", path: "/v1/repos/{owner}/{repo}/settings", diff --git a/src/services/self-dogfood-registration-pack.ts b/src/services/self-dogfood-registration-pack.ts new file mode 100644 index 00000000..903c3bdd --- /dev/null +++ b/src/services/self-dogfood-registration-pack.ts @@ -0,0 +1,161 @@ +import { + buildGittensorConfigRecommendation, + buildRegistrationReadiness, + type GittensorConfigRecommendation, + type GittensorConfigRecommendationInput, + type RegistrationReadinessInput, + type RegistrationReadinessReport, +} from "../signals/registration-readiness"; +import { nowIso } from "../utils/json"; + +export const DEFAULT_SELF_DOGFOOD_REPO = "JSONbored/gittensory"; + +export type SelfDogfoodActionArea = { + area: string; + status: "ready" | "needs_attention" | "blocked"; + actions: string[]; +}; + +export type SelfDogfoodRegistrationPack = { + kind: "gittensory_self_dogfood_registration_pack"; + repoFullName: string; + generatedAt: string; + privateOnly: true; + advisoryOnly: true; + directPrFirst: boolean; + contributorLaneStrategy: string; + maintainerEconomicsNote: string; + minerScoreabilityNote: string; + registrationReadiness: RegistrationReadinessReport; + gittensorConfigRecommendation: GittensorConfigRecommendation; + actionableAreas: SelfDogfoodActionArea[]; + rerunHint: string; +}; + +export function resolveSelfDogfoodRepoFullName(env: { GITTENSORY_DRIFT_ISSUE_REPO?: string }): string { + const configured = env.GITTENSORY_DRIFT_ISSUE_REPO?.trim(); + if (!configured || !configured.includes("/")) return DEFAULT_SELF_DOGFOOD_REPO; + return configured; +} + +export function buildSelfDogfoodRegistrationPack(args: { + repoFullName: string; + registrationReadiness: RegistrationReadinessReport; + gittensorConfigRecommendation: GittensorConfigRecommendation; +}): SelfDogfoodRegistrationPack { + const { registrationReadiness: readiness, gittensorConfigRecommendation: recommendation } = args; + const issueDiscoveryReady = + readiness.issueDiscoveryReadiness.ready && readiness.issueDiscoveryReadiness.recommendation === "enabled"; + const directPrFirst = !issueDiscoveryReady && readiness.recommendedRegistrationMode !== "issue_discovery"; + + return { + kind: "gittensory_self_dogfood_registration_pack", + repoFullName: args.repoFullName, + generatedAt: nowIso(), + privateOnly: true, + advisoryOnly: true, + directPrFirst, + contributorLaneStrategy: directPrFirst + ? "Keep contributor intake direct-PR-first until issue-discovery signals, label policy, and queue health are excellent." + : "Issue-discovery intake is strong enough to keep a bounded issue-discovery lane alongside direct PRs.", + maintainerEconomicsNote: + "Maintainer cut and registry emission splits are maintainer-economics controls only; they do not change private miner scoreability or public compensation claims.", + minerScoreabilityNote: + "Miner-facing scoreability stays in private API/MCP surfaces with hashed actors; sensitive identity and ranking fields stay out of this report.", + registrationReadiness: readiness, + gittensorConfigRecommendation: recommendation, + actionableAreas: buildActionableAreas(readiness, recommendation), + rerunHint: "Rerun this pack after registry, .gittensor.yml, label policy, GitHub App, or queue changes to refresh readiness and config tradeoffs.", + }; +} + +export function buildSelfDogfoodRegistrationPackFromSignals( + input: RegistrationReadinessInput & GittensorConfigRecommendationInput, +): SelfDogfoodRegistrationPack { + const registrationReadiness = buildRegistrationReadiness(input); + const gittensorConfigRecommendation = buildGittensorConfigRecommendation(input); + return buildSelfDogfoodRegistrationPack({ + repoFullName: input.repoFullName, + registrationReadiness, + gittensorConfigRecommendation, + }); +} + +function buildActionableAreas( + readiness: RegistrationReadinessReport, + recommendation: GittensorConfigRecommendation, +): SelfDogfoodActionArea[] { + const areas: SelfDogfoodActionArea[] = [ + { + area: "direct_pr", + status: readiness.directPrReadiness.ready ? "ready" : readiness.blockers.length > 0 ? "blocked" : "needs_attention", + actions: readiness.directPrReadiness.ready + ? ["Keep direct PRs as the default contributor lane."] + : [...readiness.directPrReadiness.reasons, ...readiness.blockers], + }, + { + area: "issue_discovery", + status: + readiness.issueDiscoveryReadiness.recommendation === "not_recommended" + ? "blocked" + : readiness.issueDiscoveryReadiness.ready + ? "ready" + : "needs_attention", + actions: + readiness.issueDiscoveryReadiness.reasons.length > 0 + ? readiness.issueDiscoveryReadiness.reasons + : ["Issue discovery is intentionally deprioritized until intake is staffed and config is excellent."], + }, + { + area: "label_policy", + status: readiness.labelPolicy.trustedPipelineReady ? "ready" : "needs_attention", + actions: [ + ...(readiness.labelPolicy.missingOrUnusedRegistryLabels.length > 0 + ? readiness.labelPolicy.missingOrUnusedRegistryLabels.map((label) => `Add or retire registry label "${label}".`) + : ["Label policy matches cached repo activity."]), + recommendation.recommended.labelMultipliers === "start_without_trusted_label_multipliers" + ? "Start without trusted label multipliers until labels are observed in live activity." + : "Prune unused configured labels before expanding trusted multipliers.", + ], + }, + { + area: "maintainer_cut", + status: readiness.maintainerCutReadiness.ready ? "ready" : "needs_attention", + actions: readiness.maintainerCutReadiness.ready + ? [`Consider maintainer cut near ${recommendation.recommended.maintainerCut}; keep it separate from miner scoreability.`] + : readiness.maintainerCutReadiness.reasons, + }, + { + area: "tests_and_docs", + status: readiness.testCoverageHealth.status === "gate_ready" ? "ready" : "needs_attention", + actions: [ + ...readiness.testCoverageHealth.requiredGate.map((gate) => `Preserve CI gate: ${gate}.`), + ...readiness.docsCompleteness.requiredDocs.map((doc) => `Keep ${doc} current for contributor intake.`), + ], + }, + { + area: "queue_and_github_app", + status: + readiness.queueHealth.level === "critical" || readiness.queueHealth.level === "high" + ? "blocked" + : readiness.githubApp.installed + ? "ready" + : "needs_attention", + actions: [ + readiness.queueHealth.summary, + readiness.githubApp.behavior, + ...readiness.githubApp.warnings, + ].filter(Boolean), + }, + ]; + + if (readiness.blockers.length > 0) { + areas.unshift({ + area: "registration_blockers", + status: "blocked", + actions: readiness.blockers, + }); + } + + return areas; +} diff --git a/test/unit/self-dogfood-registration-pack.test.ts b/test/unit/self-dogfood-registration-pack.test.ts new file mode 100644 index 00000000..4440b15e --- /dev/null +++ b/test/unit/self-dogfood-registration-pack.test.ts @@ -0,0 +1,203 @@ +import { describe, expect, it } from "vitest"; +import { + buildCollisionReport, + buildConfigQuality, + buildContributorIntakeHealth, + buildLabelAudit, + buildLaneAdvice, + buildMaintainerCutReadiness, + buildQueueHealth, +} from "../../src/signals/engine"; +import { + buildSelfDogfoodRegistrationPack, + buildSelfDogfoodRegistrationPackFromSignals, + DEFAULT_SELF_DOGFOOD_REPO, + resolveSelfDogfoodRepoFullName, + type SelfDogfoodRegistrationPack, +} from "../../src/services/self-dogfood-registration-pack"; +import { + buildGittensorConfigRecommendation, + buildRegistrationReadiness, + type InstallationHealthSummary, +} from "../../src/signals/registration-readiness"; +import type { IssueRecord, PullRequestRecord, RepoLabelRecord, RegistryRepoConfig, RepositoryRecord, RepositorySettings } from "../../src/types"; + +const FORBIDDEN_PUBLIC_LANGUAGE = + /wallet|hotkey|payout|reward estimate|raw trust score|public score estimate|private reviewability|farming/i; + +function repoFor(fullName: string, registryConfig: RegistryRepoConfig | null, overrides: Partial = {}): RepositoryRecord { + const [owner, name] = fullName.split("/"); + return { + fullName, + owner: owner ?? fullName, + name: name ?? fullName, + installationId: 1, + isInstalled: true, + isRegistered: registryConfig !== null, + isPrivate: false, + registryConfig, + ...overrides, + }; +} + +function configFor(overrides: Partial = {}): RegistryRepoConfig { + return { repo: "x/y", emissionShare: 0.02, issueDiscoveryShare: 0, labelMultipliers: { bug: 1.1 }, trustedLabelPipeline: true, maintainerCut: 0, raw: {}, ...overrides }; +} + +function settingsFor(repoFullName: string, overrides: Partial = {}): RepositorySettings { + return { + repoFullName, + commentMode: "detected_contributors_only", + publicSignalLevel: "standard", + checkRunMode: "enabled", + checkRunDetailLevel: "standard", + autoLabelEnabled: true, + gittensorLabel: "gittensor", + createMissingLabel: true, + publicSurface: "comment_and_label", + includeMaintainerAuthors: false, + requireLinkedIssue: false, + backfillEnabled: true, + privateTrustEnabled: true, + ...overrides, + }; +} + +const healthyInstall: InstallationHealthSummary = { status: "healthy", missingPermissions: [], missingEvents: [] }; + +function signalsFor(repo: RepositoryRecord, issues: IssueRecord[], pullRequests: PullRequestRecord[], labels: RepoLabelRecord[]) { + const fullName = repo.fullName; + const collisions = buildCollisionReport(fullName, issues, pullRequests); + return { + lane: buildLaneAdvice(repo, fullName), + configQuality: buildConfigQuality(repo, issues, pullRequests, fullName), + labelAudit: buildLabelAudit(repo, labels, issues, pullRequests, fullName), + queueHealth: buildQueueHealth(repo, issues, pullRequests, collisions), + maintainerCutReadiness: buildMaintainerCutReadiness(repo, issues, pullRequests, fullName, {}, collisions), + contributorIntakeHealth: buildContributorIntakeHealth(repo, issues, pullRequests, fullName, collisions), + }; +} + +function label(name: string): RepoLabelRecord { + return { repoFullName: "x/y", name, isConfigured: true, observedCount: 3, payload: {} }; +} + +function packFromRepo( + repo: RepositoryRecord, + issues: IssueRecord[] = [], + pullRequests: PullRequestRecord[] = [], + labels: RepoLabelRecord[] = [label("bug")], + settingsOverrides: Partial = {}, +): SelfDogfoodRegistrationPack { + return buildSelfDogfoodRegistrationPackFromSignals({ + repoFullName: repo.fullName, + repo, + settings: settingsFor(repo.fullName, settingsOverrides), + installation: healthyInstall, + ...signalsFor(repo, issues, pullRequests, labels), + }); +} + +describe("resolveSelfDogfoodRepoFullName", () => { + it("defaults to the Gittensory repo when drift issue repo is unset", () => { + expect(resolveSelfDogfoodRepoFullName({})).toBe(DEFAULT_SELF_DOGFOOD_REPO); + expect(resolveSelfDogfoodRepoFullName({ GITTENSORY_DRIFT_ISSUE_REPO: "" })).toBe(DEFAULT_SELF_DOGFOOD_REPO); + }); + + it("uses the configured drift issue repo when valid", () => { + expect(resolveSelfDogfoodRepoFullName({ GITTENSORY_DRIFT_ISSUE_REPO: "acme/widget" })).toBe("acme/widget"); + }); +}); + +describe("buildSelfDogfoodRegistrationPack", () => { + it("ready fixture recommends direct-PR-first with actionable areas", () => { + const repo = repoFor("octo/ready", configFor({ repo: "octo/ready" })); + const issues: IssueRecord[] = [{ repoFullName: repo.fullName, number: 4, title: "Fix flaky cache test", state: "open", labels: ["bug"], linkedPrs: [] }]; + const pack = packFromRepo(repo, issues); + + expect(pack).toMatchObject({ + kind: "gittensory_self_dogfood_registration_pack", + privateOnly: true, + advisoryOnly: true, + directPrFirst: true, + registrationReadiness: { ready: true, recommendedRegistrationMode: "direct_pr" }, + }); + expect(pack.actionableAreas.some((area) => area.area === "direct_pr" && area.status === "ready")).toBe(true); + expect(pack.maintainerEconomicsNote).toMatch(/maintainer-economics/i); + expect(pack.minerScoreabilityNote).toMatch(/scoreability/i); + expect(pack.rerunHint).toMatch(/Rerun this pack/i); + }); + + it("not-ready fixture surfaces registration blockers", () => { + const repo = repoFor("octo/unregistered", null); + const pack = packFromRepo(repo, [], [], []); + + expect(pack.registrationReadiness.ready).toBe(false); + expect(pack.directPrFirst).toBe(true); + expect(pack.actionableAreas[0]).toMatchObject({ area: "registration_blockers", status: "blocked" }); + expect(pack.gittensorConfigRecommendation.recommended.issueDiscoveryShare).toBe(0); + }); + + it("issue-discovery disabled fixture keeps direct PR lane primary", () => { + const repo = repoFor("octo/direct", configFor({ repo: "octo/direct", issueDiscoveryShare: 0 })); + const base = signalsFor(repo, [], [], [label("bug")]); + const pack = buildSelfDogfoodRegistrationPackFromSignals({ + repoFullName: repo.fullName, + repo, + settings: settingsFor(repo.fullName), + installation: healthyInstall, + ...base, + contributorIntakeHealth: { ...base.contributorIntakeHealth, level: "strained" }, + }); + + expect(pack.registrationReadiness.issueDiscoveryReadiness.recommendation).toBe("not_recommended"); + expect(pack.directPrFirst).toBe(true); + expect(pack.contributorLaneStrategy).toMatch(/direct-PR-first/i); + expect(pack.gittensorConfigRecommendation.recommended.participationMode).toBe("direct_pr"); + expect(pack.gittensorConfigRecommendation.recommended.issueDiscoveryShare).toBe(0); + }); + + it("maintainer-cut fixture separates economics from miner scoreability", () => { + const repo = repoFor("octo/cut", configFor({ repo: "octo/cut", maintainerCut: 0.05 })); + const base = signalsFor(repo, [], [], [label("bug")]); + const pack = buildSelfDogfoodRegistrationPackFromSignals({ + repoFullName: repo.fullName, + repo, + settings: settingsFor(repo.fullName), + installation: healthyInstall, + ...base, + maintainerCutReadiness: { ...base.maintainerCutReadiness, ready: true }, + }); + + expect(pack.actionableAreas.some((area) => area.area === "maintainer_cut")).toBe(true); + expect(pack.maintainerEconomicsNote).not.toMatch(FORBIDDEN_PUBLIC_LANGUAGE); + expect(pack.minerScoreabilityNote).toMatch(/private API\/MCP surfaces/i); + }); + + it("public wording regression stays free of forbidden language", () => { + const repo = repoFor("JSONbored/gittensory", configFor({ repo: "JSONbored/gittensory" })); + const pack = packFromRepo(repo); + expect(JSON.stringify(pack)).not.toMatch(FORBIDDEN_PUBLIC_LANGUAGE); + }); + + it("composes from explicit readiness and recommendation payloads", () => { + const repo = repoFor("octo/ready", configFor({ repo: "octo/ready" })); + const signals = signalsFor(repo, [], [], [label("bug")]); + const registrationReadiness = buildRegistrationReadiness({ + repoFullName: repo.fullName, + repo, + settings: settingsFor(repo.fullName), + installation: healthyInstall, + ...signals, + }); + const gittensorConfigRecommendation = buildGittensorConfigRecommendation({ + repoFullName: repo.fullName, + repo, + settings: settingsFor(repo.fullName), + ...signals, + }); + const pack = buildSelfDogfoodRegistrationPack({ repoFullName: repo.fullName, registrationReadiness, gittensorConfigRecommendation }); + expect(pack.repoFullName).toBe("octo/ready"); + expect(pack.registrationReadiness).toBe(registrationReadiness); + }); +}); From 0a05e99081d1706fae5eba8a448d4b37e4f0aa24 Mon Sep 17 00:00:00 2001 From: kiannidev <156195510+kiannidev@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:30:41 +0200 Subject: [PATCH 2/5] test(registration): raise self-dogfood pack branch coverage above gate Cover issue-discovery-enabled, actionable-area branches, and invalid drift-repo fallback so global branch coverage stays at or above 97%. --- .../self-dogfood-registration-pack.test.ts | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/test/unit/self-dogfood-registration-pack.test.ts b/test/unit/self-dogfood-registration-pack.test.ts index e0d73a26..3e95b72d 100644 --- a/test/unit/self-dogfood-registration-pack.test.ts +++ b/test/unit/self-dogfood-registration-pack.test.ts @@ -18,7 +18,9 @@ import { import { buildGittensorConfigRecommendation, buildRegistrationReadiness, + type GittensorConfigRecommendation, type InstallationHealthSummary, + type RegistrationReadinessReport, } from "../../src/signals/registration-readiness"; import type { IssueRecord, PullRequestRecord, RepoLabelRecord, RegistryRepoConfig, RepositoryRecord, RepositorySettings } from "../../src/types"; @@ -84,6 +86,95 @@ function label(name: string): RepoLabelRecord { return { repoFullName: "x/y", name, isConfigured: true, observedCount: 3, payload: {} }; } +function readinessFixture(overrides: Partial = {}): RegistrationReadinessReport { + return { + repoFullName: "octo/test", + generatedAt: "2026-05-28T00:00:00.000Z", + ready: true, + recommendedRegistrationMode: "split", + issuePolicy: "split_pr_and_issue_discovery_enabled", + directPrReadiness: { ready: false, reasons: ["Direct PR lane still needs maintainer review staffing."] }, + issueDiscoveryReadiness: { ready: true, recommendation: "enabled", reasons: ["Issue discovery lane is staffed."] }, + labelPolicy: { + autoLabelEnabled: true, + label: "gittensor", + createMissingLabel: true, + configuredRegistryLabels: ["bug"], + missingOrUnusedRegistryLabels: ["stale-label"], + trustedPipelineReady: false, + }, + maintainerCutReadiness: { + repoFullName: "octo/test", + generatedAt: "2026-05-28T00:00:00.000Z", + ready: false, + maintainerCut: 0, + recommendedAction: "leave_disabled", + reasons: ["Maintainer cut stays off until config is excellent."], + warnings: [], + }, + testCoverageHealth: { + status: "gate_unknown", + trustedLabelPipelineReady: false, + checkRunMode: "off", + requiredGate: ["npm run test:ci"], + note: "Coverage gate note.", + warnings: [], + }, + queueHealth: { level: "high", burdenScore: 88, reviewablePullRequests: 0, summary: "Queue burden is high." }, + contributorIntakeHealth: { + repoFullName: "octo/test", + generatedAt: "2026-05-28T00:00:00.000Z", + level: "healthy", + score: 90, + queueHealth: { burdenScore: 88, level: "high", signals: [] }, + configLevel: "excellent", + duplicateClusters: 0, + reviewablePullRequests: 0, + summary: "Healthy intake.", + findings: [], + }, + docsCompleteness: { status: "repo_docs_not_crawled", requiredDocs: ["README"], note: "Docs not crawled." }, + githubApp: { + installed: false, + publicSurface: "comment_and_label", + commentMode: "all_prs", + publicAudienceMode: "oss_maintainer", + checkRunMode: "off", + gateCheckMode: "off", + quietByDefault: false, + behavior: "Gittensory would stay silent because the GitHub App is not installed.", + warnings: ["GitHub App is not installed on this repo; maintainers will not get any automated assistance."], + }, + policyReadiness: null, + blockers: [], + warnings: [], + ...overrides, + }; +} + +function recommendationFixture(overrides: Partial = {}): GittensorConfigRecommendation { + return { + repoFullName: "octo/test", + generatedAt: "2026-05-28T00:00:00.000Z", + privateOnly: true, + current: null, + recommended: { + participationMode: "split", + issueDiscoveryShare: 0.1, + directPrShare: 0.9, + maintainerCut: 0, + requireLinkedIssue: false, + labelMultipliers: "start_without_trusted_label_multipliers", + publicSurface: "comment_and_label", + confirmedMinerLabel: "gittensor", + }, + tradeoffs: [], + reasons: [], + warnings: [], + ...overrides, + }; +} + function packFromRepo( repo: RepositoryRecord, issues: IssueRecord[] = [], @@ -109,6 +200,10 @@ describe("resolveSelfDogfoodRepoFullName", () => { it("uses the configured drift issue repo when valid", () => { expect(resolveSelfDogfoodRepoFullName({ GITTENSORY_DRIFT_ISSUE_REPO: "acme/widget" })).toBe("acme/widget"); }); + + it("falls back when drift issue repo is missing a slash", () => { + expect(resolveSelfDogfoodRepoFullName({ GITTENSORY_DRIFT_ISSUE_REPO: "invalid" })).toBe(DEFAULT_SELF_DOGFOOD_REPO); + }); }); describe("buildSelfDogfoodRegistrationPack", () => { @@ -182,6 +277,73 @@ describe("buildSelfDogfoodRegistrationPack", () => { expect(JSON.stringify(pack)).not.toMatch(FORBIDDEN_PUBLIC_LANGUAGE); }); + it("issue-discovery enabled fixture keeps bounded issue-discovery lane guidance", () => { + const pack = buildSelfDogfoodRegistrationPack({ + repoFullName: "octo/split", + registrationReadiness: readinessFixture(), + gittensorConfigRecommendation: recommendationFixture(), + }); + + expect(pack.directPrFirst).toBe(false); + expect(pack.contributorLaneStrategy).toMatch(/bounded issue-discovery lane/i); + expect(pack.actionableAreas).toEqual( + expect.arrayContaining([ + expect.objectContaining({ area: "direct_pr", status: "needs_attention" }), + expect.objectContaining({ area: "issue_discovery", status: "ready" }), + expect.objectContaining({ area: "queue_and_github_app", status: "blocked" }), + ]), + ); + }); + + it("actionable areas cover deprioritized issue discovery and label-prune guidance", () => { + const pack = buildSelfDogfoodRegistrationPack({ + repoFullName: "octo/labels", + registrationReadiness: readinessFixture({ + directPrReadiness: { ready: true, reasons: [] }, + issueDiscoveryReadiness: { ready: false, recommendation: "recommended", reasons: [] }, + queueHealth: { level: "low", burdenScore: 10, reviewablePullRequests: 2, summary: "Queue is manageable." }, + githubApp: { + installed: true, + publicSurface: "comment_and_label", + commentMode: "all_prs", + publicAudienceMode: "oss_maintainer", + checkRunMode: "off", + gateCheckMode: "off", + quietByDefault: false, + behavior: "Gittensory posts comment and label in oss maintainer mode, for all PRs.", + warnings: [], + }, + }), + gittensorConfigRecommendation: recommendationFixture({ + recommended: { + participationMode: "direct_pr", + issueDiscoveryShare: 0, + directPrShare: 1, + maintainerCut: 0, + requireLinkedIssue: false, + labelMultipliers: "keep_current_and_prune_unused", + publicSurface: "comment_and_label", + confirmedMinerLabel: "gittensor", + }, + }), + }); + + expect(pack.actionableAreas).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + area: "issue_discovery", + status: "needs_attention", + actions: ["Issue discovery is intentionally deprioritized until intake is staffed and config is excellent."], + }), + expect.objectContaining({ + area: "label_policy", + actions: expect.arrayContaining(["Prune unused configured labels before expanding trusted multipliers."]), + }), + expect.objectContaining({ area: "queue_and_github_app", status: "ready" }), + ]), + ); + }); + it("composes from explicit readiness and recommendation payloads", () => { const repo = repoFor("octo/ready", configFor({ repo: "octo/ready" })); const signals = signalsFor(repo, [], [], [label("bug")]); From 60557a3756854a89be363827f3f6096c01419178 Mon Sep 17 00:00:00 2001 From: kiannidev <156195510+kiannidev@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:36:33 +0200 Subject: [PATCH 3/5] test(registration): fix queueHealth signals fixture typing Use a full QueueHealth signals object in the self-dogfood registration pack fixture so typecheck passes in CI. --- test/unit/self-dogfood-registration-pack.test.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/unit/self-dogfood-registration-pack.test.ts b/test/unit/self-dogfood-registration-pack.test.ts index 3e95b72d..d9280984 100644 --- a/test/unit/self-dogfood-registration-pack.test.ts +++ b/test/unit/self-dogfood-registration-pack.test.ts @@ -126,7 +126,20 @@ function readinessFixture(overrides: Partial = {}): generatedAt: "2026-05-28T00:00:00.000Z", level: "healthy", score: 90, - queueHealth: { burdenScore: 88, level: "high", signals: [] }, + queueHealth: { + burdenScore: 88, + level: "high", + signals: { + openIssues: 4, + openPullRequests: 6, + unlinkedPullRequests: 1, + stalePullRequests: 2, + maintainerAuthoredPullRequests: 0, + collisionClusters: 0, + ageBuckets: { under7Days: 2, days7To30: 3, over30Days: 1 }, + likelyReviewablePullRequests: 0, + }, + }, configLevel: "excellent", duplicateClusters: 0, reviewablePullRequests: 0, From b483ef3665b6050f8f5ea059606ee4ceede3528e Mon Sep 17 00:00:00 2001 From: kiannidev <156195510+kiannidev@users.noreply.github.com> Date: Sat, 6 Jun 2026 02:34:33 +0200 Subject: [PATCH 4/5] fix(ci): restore RepositorySettings fields and branch coverage for PR #388 Add missing gate-mode settings to self-dogfood tests after main merge, and cover quiet public-surface plus unsafe publicNotes policy paths to clear the 97% branch coverage gate. Co-authored-by: Cursor --- test/unit/focus-manifest.test.ts | 26 +++++++++++++++++++ test/unit/registration-readiness.test.ts | 15 +++++++++++ .../self-dogfood-registration-pack.test.ts | 4 +++ 3 files changed, 45 insertions(+) diff --git a/test/unit/focus-manifest.test.ts b/test/unit/focus-manifest.test.ts index 804c2e6b..46416729 100644 --- a/test/unit/focus-manifest.test.ts +++ b/test/unit/focus-manifest.test.ts @@ -119,6 +119,14 @@ describe("parseFocusManifestContent", () => { expect(manifest.present).toBe(false); expect(manifest.warnings.join(" ")).toMatch(/not valid JSON/i); }); + + it("warns when JSON content is not a mapping", () => { + for (const content of ['["a","b"]', '"string"']) { + const manifest = parseFocusManifestContent(content); + expect(manifest.present).toBe(false); + expect(manifest.warnings.join(" ")).toMatch(/must be a mapping/i); + } + }); }); describe("matchesManifestPath", () => { @@ -365,6 +373,24 @@ describe("compileFocusManifestPolicy", () => { expect(publicText).toContain("npm run test:ci"); }); + it("skips unsafe publicNotes when entry guidance is compiled from a raw manifest", () => { + const policy = compileFocusManifestPolicy({ + present: true, + source: "api_record", + wantedPaths: ["src/"], + blockedPaths: [], + preferredLabels: [], + linkedIssuePolicy: "optional", + testExpectations: [], + issueDiscoveryPolicy: "neutral", + maintainerNotes: [], + publicNotes: ["Keep PRs focused.", "Maximize your reward payout"], + warnings: [], + }); + expect(policy.publicSafe.entryGuidance).toContain("Keep PRs focused."); + expect(policy.publicSafe.entryGuidance.join(" ")).not.toMatch(/reward payout/i); + }); + it("publicSafe.summary never contains forbidden language", () => { const dangerous = parseFocusManifest({ wantedPaths: ["src/"], publicNotes: ["Boost your raw trust score here"] }); const policy = compileFocusManifestPolicy(dangerous); diff --git a/test/unit/registration-readiness.test.ts b/test/unit/registration-readiness.test.ts index 7ef1c68c..f4026d3c 100644 --- a/test/unit/registration-readiness.test.ts +++ b/test/unit/registration-readiness.test.ts @@ -161,6 +161,21 @@ describe("buildRegistrationReadiness", () => { expect(report.githubApp.behavior).toContain("for all PRs"); }); + it("describes a quiet public surface while keeping the opt-in gate check enabled", () => { + const repo = repoFor("octo/quiet-gate", configFor({ repo: "octo/quiet-gate" })); + const settings = settingsFor(repo.fullName, { publicSurface: "off", gateCheckMode: "enabled" }); + const report = buildRegistrationReadiness({ + repoFullName: repo.fullName, + repo, + settings, + installation: healthyInstall, + ...signalsFor(repo, [], [], [label("bug")]), + }); + + expect(report.githubApp.behavior).toContain("stays quiet"); + expect(report.githubApp.behavior).toContain("opt-in gate check still enabled"); + }); + it("notes when the GitHub App is not installed", () => { const repo = repoFor("octo/uninstalled", configFor({ repo: "octo/uninstalled" }), { isInstalled: false, installationId: null }); const report = buildRegistrationReadiness({ repoFullName: repo.fullName, repo, settings: settingsFor(repo.fullName), installation: null, ...signalsFor(repo, [], [], [label("bug")]) }); diff --git a/test/unit/self-dogfood-registration-pack.test.ts b/test/unit/self-dogfood-registration-pack.test.ts index d9280984..21022cfe 100644 --- a/test/unit/self-dogfood-registration-pack.test.ts +++ b/test/unit/self-dogfood-registration-pack.test.ts @@ -55,6 +55,10 @@ function settingsFor(repoFullName: string, overrides: Partial Date: Sat, 6 Jun 2026 02:37:35 +0200 Subject: [PATCH 5/5] chore(ui): refresh OpenAPI spec for CI ui:openapi:check Regenerate apps/gittensory-ui/public/openapi.json from the current API schema so the UI check step passes on PR #388. Co-authored-by: Cursor --- apps/gittensory-ui/public/openapi.json | 28 -------------------------- 1 file changed, 28 deletions(-) diff --git a/apps/gittensory-ui/public/openapi.json b/apps/gittensory-ui/public/openapi.json index ce02e79e..f7a7e78d 100644 --- a/apps/gittensory-ui/public/openapi.json +++ b/apps/gittensory-ui/public/openapi.json @@ -7647,20 +7647,6 @@ "type": "string", "nullable": true }, - "publicAudienceMode": { - "type": "string", - "enum": [ - "oss_maintainer", - "gittensor_only" - ] - }, - "gateCheckMode": { - "type": "string", - "enum": [ - "off", - "enabled" - ] - }, "linkedIssueGateMode": { "type": "string", "enum": [ @@ -8233,20 +8219,6 @@ "commandOverrides" ] }, - "publicAudienceMode": { - "type": "string", - "enum": [ - "oss_maintainer", - "gittensor_only" - ] - }, - "gateCheckMode": { - "type": "string", - "enum": [ - "off", - "enabled" - ] - }, "linkedIssueGateMode": { "type": "string", "enum": [