From f71d2a4bdf5b2d9c3932275590c17048de3b090b Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Thu, 2 Jul 2026 05:04:59 -0700 Subject: [PATCH] fix(config): wire badgeEnabled into the .gittensory.yml manifest parser .gittensory.yml.example documents badgeEnabled under settings: as a config-as-code-settable field, and it's fully wired everywhere else (DB column, RepositorySettings type, API, the badge consumer) -- but FocusManifestSettings's Pick list and parseSettingsOverride both omitted it, so a maintainer setting it in .gittensory.yml had the value silently ignored. Added badgeEnabled to the manifest Pick-list and the existing boolean-field normalization loop in parseSettingsOverride, mirroring autoLabelEnabled exactly. resolveEffectiveSettings needs no change -- it spreads settings.* generically, so the field now overrides the DB value automatically. Added a regression test proving the override actually takes effect. Closes #2555 --- src/signals/focus-manifest.ts | 3 ++- test/unit/focus-manifest.test.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/signals/focus-manifest.ts b/src/signals/focus-manifest.ts index 81c20e1ae3..0b57e9be5b 100644 --- a/src/signals/focus-manifest.ts +++ b/src/signals/focus-manifest.ts @@ -120,6 +120,7 @@ export type FocusManifestSettings = Partial< | "aiReviewAllAuthors" | "closeOwnerAuthors" | "autoLabelEnabled" + | "badgeEnabled" | "gittensorLabel" | "createMissingLabel" | "publicSurface" @@ -773,7 +774,7 @@ function parseSettingsOverride(value: JsonValue | undefined, warnings: string[]) if (blacklistLabel !== null) out.blacklistLabel = blacklistLabel; const publicSurface = normalizeOptionalEnum(r.publicSurface, "settings.publicSurface", ["off", "comment_and_label", "comment_only", "label_only"] as const, warnings); if (publicSurface !== null) out.publicSurface = publicSurface; - for (const key of ["aiReviewByok", "aiReviewAllAuthors", "closeOwnerAuthors", "autoLabelEnabled", "createMissingLabel", "includeMaintainerAuthors", "requireLinkedIssue", "backfillEnabled", "privateTrustEnabled", "agentPaused", "agentDryRun"] as const) { + for (const key of ["aiReviewByok", "aiReviewAllAuthors", "closeOwnerAuthors", "autoLabelEnabled", "badgeEnabled", "createMissingLabel", "includeMaintainerAuthors", "requireLinkedIssue", "backfillEnabled", "privateTrustEnabled", "agentPaused", "agentDryRun"] as const) { const flag = normalizeOptionalBoolean(r[key], `settings.${key}`, warnings); if (flag !== null) out[key] = flag; } diff --git a/test/unit/focus-manifest.test.ts b/test/unit/focus-manifest.test.ts index 61d81bbd50..508e7cbbae 100644 --- a/test/unit/focus-manifest.test.ts +++ b/test/unit/focus-manifest.test.ts @@ -1426,6 +1426,18 @@ describe("parseFocusManifest settings override + resolveEffectiveSettings", () = expect(eff.linkedIssueGateMode).toBe("block"); // gate: wins over settings: }); + it("wires settings.badgeEnabled into the manifest parser and lets it override the DB value (#2555)", () => { + const parsedTrue = parseFocusManifest({ settings: { badgeEnabled: true } }); + expect(parsedTrue.settings.badgeEnabled).toBe(true); + expect(parsedTrue.warnings).toEqual([]); + const parsedFalse = parseFocusManifest({ settings: { badgeEnabled: false } }); + expect(parsedFalse.settings.badgeEnabled).toBe(false); + + const db = { badgeEnabled: false } as unknown as RepositorySettings; + const eff = resolveEffectiveSettings(db, parseFocusManifest({ settings: { badgeEnabled: true } })); + expect(eff.badgeEnabled).toBe(true); // settings: override wins over the DB-stored value + }); + it("parses aiReview from settings: and lets gate.aiReview win in resolveEffectiveSettings", () => { const parsed = parseFocusManifest({ settings: { aiReviewMode: "advisory", aiReviewByok: true } }); expect(parsed.settings.aiReviewMode).toBe("advisory");