diff --git a/packages/gittensory-engine/src/focus-manifest.ts b/packages/gittensory-engine/src/focus-manifest.ts index 2d7254a677..2aeb0c5728 100644 --- a/packages/gittensory-engine/src/focus-manifest.ts +++ b/packages/gittensory-engine/src/focus-manifest.ts @@ -67,11 +67,11 @@ export type FocusManifestIssueDiscoveryPolicy = "encouraged" | "neutral" | "disc * field is `null` when the maintainer did not set it, so the resolver can layer the manifest OVER the * DB-backed RepositorySettings (manifest > DB > safe defaults) without clobbering unset values. All * of these flow through the SAME confirmed-contributor-gated `evaluateGateCheck` path — the manifest - * only chooses which deterministic blockers are active, never who can be blocked. Turning the gate - * itself on/off stays a repository setting (`gateCheckMode`); `.gittensory.yml gate:` refines the - * blocker policy of an already-enabled gate. `checkMode` (#2852) is a separate, more expressive axis: - * whether/how the "Gittensory Orb Review Agent" check-RUN publishes, independent of gate evaluation - * itself (which always runs regardless of `checkMode`/`enabled`) — see {@link ReviewCheckMode}. + * only chooses which deterministic blockers are active, never who can be blocked. There is no single + * gate master switch: each per-dimension mode (`linkedIssue`, `duplicates`, `readinessMode`, etc.) + * independently controls whether that dimension evaluates. `checkMode`/`enabled` (#2852) is a separate + * axis entirely: whether/how the "Gittensory Orb Review Agent" check-RUN publishes, independent of gate + * evaluation itself (which always runs regardless of `checkMode`/`enabled`) — see {@link ReviewCheckMode}. */ export type FocusManifestGateConfig = { present: boolean; @@ -373,7 +373,6 @@ export type FocusManifestSettings = Partial< | "publicSignalLevel" | "checkRunMode" | "checkRunDetailLevel" - | "gateCheckMode" | "regateSweepOrderMode" | "reviewCheckMode" | "autoProjectMilestoneMatch" @@ -1815,19 +1814,12 @@ function parseSettingsOverride(value: JsonValue | undefined, warnings: string[], if (checkRunMode !== null) out.checkRunMode = checkRunMode; const checkRunDetailLevel = normalizeOptionalEnum(r.checkRunDetailLevel, "settings.checkRunDetailLevel", ["minimal", "standard"] as const, warnings); if (checkRunDetailLevel !== null) out.checkRunDetailLevel = checkRunDetailLevel; - // #4618: gateCheckMode is deprecated (a computed read-back value everywhere else) but this yml key still - // parses for back-compat with existing `.gittensory.yml` files. A manifest setting ONLY gateCheckMode - // (never the more expressive reviewCheckMode) must keep its historical effect on the actual publish - // authority -- derive reviewCheckMode from it below when reviewCheckMode itself is unset. - const gateCheckMode = normalizeOptionalEnum(r.gateCheckMode, "settings.gateCheckMode", ["off", "enabled"] as const, warnings); - if (gateCheckMode !== null) out.gateCheckMode = gateCheckMode; const regateSweepOrderMode = normalizeOptionalEnum(r.regateSweepOrderMode, "settings.regateSweepOrderMode", ["staleness", "oldest-first"] as const, warnings); if (regateSweepOrderMode !== null) out.regateSweepOrderMode = regateSweepOrderMode; // Same tri-state field as gate.checkMode above (the friendly gate alias overlays onto it in // resolveEffectiveSettings, and wins when both are set). const reviewCheckMode = normalizeOptionalEnum(r.reviewCheckMode, "settings.reviewCheckMode", ["required", "visible", "disabled"] as const, warnings); if (reviewCheckMode !== null) out.reviewCheckMode = reviewCheckMode; - else if (gateCheckMode !== null) out.reviewCheckMode = gateCheckMode === "enabled" ? "required" : "disabled"; const autoProjectMilestoneMatch = normalizeOptionalEnum(r.autoProjectMilestoneMatch, "settings.autoProjectMilestoneMatch", ["off", "suggest", "auto"] as const, warnings); if (autoProjectMilestoneMatch !== null) out.autoProjectMilestoneMatch = autoProjectMilestoneMatch; const autoProjectMilestoneMatchBackend = normalizeOptionalEnum(r.autoProjectMilestoneMatchBackend, "settings.autoProjectMilestoneMatchBackend", ["github", "linear"] as const, warnings); diff --git a/packages/gittensory-engine/src/types/manifest-deps-types.ts b/packages/gittensory-engine/src/types/manifest-deps-types.ts index f55eb08d88..8f0749e288 100644 --- a/packages/gittensory-engine/src/types/manifest-deps-types.ts +++ b/packages/gittensory-engine/src/types/manifest-deps-types.ts @@ -155,10 +155,6 @@ export type RepositorySettings = { publicSignalLevel: "minimal" | "standard"; checkRunMode: "off" | "enabled"; checkRunDetailLevel: "minimal" | "standard"; - /** @deprecated (#4618, being removed per #5373) computed read-back of {@link reviewCheckMode} below, - * kept only for API/dashboard back-compat display -- read `reviewCheckMode` instead. Optional (widened - * ahead of full removal) so callers building a partial RepositorySettings no longer need to supply it. */ - gateCheckMode?: "off" | "enabled" | undefined; /** Scheduled re-gate sweep candidate ordering (#3815). `staleness` (default) picks whichever open PR the * sweep has gone longest WITHOUT re-gating (see selectRegateCandidates), which is what gives the sweep its * documented full-coverage-in-ceil(open/max)-ticks convergence guarantee even under dry-run/pause (when @@ -168,8 +164,7 @@ export type RepositorySettings = { * any time regardless of the chosen order. */ regateSweepOrderMode: "staleness" | "oldest-first"; /** The actual runtime authority for whether the "Gittensory Orb Review Agent" check-run publishes (#2852). - * See {@link ReviewCheckMode}. `gateCheckMode` above stays wired for API/back-compat display but no longer - * drives the publish decision on its own. */ + * See {@link ReviewCheckMode}. */ reviewCheckMode: ReviewCheckMode; /** Auto-project/milestone matching (#3183). See {@link ProjectMilestoneMatchMode}. Always populated by the DB * layer (default `"off"`); optional so existing settings fixtures/callers need not be touched. */ diff --git a/scripts/check-docs-drift.mjs b/scripts/check-docs-drift.mjs index 8fd310b243..f7b0415042 100644 --- a/scripts/check-docs-drift.mjs +++ b/scripts/check-docs-drift.mjs @@ -129,7 +129,6 @@ const NOT_YML_CONFIGURABLE_SETTINGS_FIELDS = new Set([ * alias per row is enough. Any `*GateMode` field is deliberately absent from this manifest even though its own * yml key is ALSO renamed the same way -- GATE_MODE_MANIFEST above already owns that exhaustive cross-check. */ export const SETTINGS_ALIAS_MANIFEST = [ - { field: "gateCheckMode", aliases: ["checkMode"] }, { field: "reviewCheckMode", aliases: ["checkMode"] }, { field: "gatePack", aliases: ["pack:"] }, { field: "qualityGateMinScore", aliases: ["minScore"] }, diff --git a/test/unit/focus-manifest.test.ts b/test/unit/focus-manifest.test.ts index e3cbe4251c..61907a5a27 100644 --- a/test/unit/focus-manifest.test.ts +++ b/test/unit/focus-manifest.test.ts @@ -293,7 +293,7 @@ describe(".gittensory.yml.example field-exhaustiveness (#1670)", () => { // Settings fields that are raw aliases of an already-documented `gate:` field (see the describe-block // comment above) -- intentionally NOT in SETTINGS_FIELD_TOKENS, so they must be listed here instead of // silently vanishing from the exhaustiveness check. - const SETTINGS_GATE_ALIASED_FIELDS = ["gateCheckMode", "linkedIssueGateMode", "duplicatePrGateMode", "selfAuthoredLinkedIssueGateMode", "qualityGateMode", "qualityGateMinScore", "aiReviewMode", "aiReviewByok", "aiReviewProvider", "aiReviewModel", "aiReviewAllAuthors"] as const; + const SETTINGS_GATE_ALIASED_FIELDS = ["linkedIssueGateMode", "duplicatePrGateMode", "selfAuthoredLinkedIssueGateMode", "qualityGateMode", "qualityGateMinScore", "aiReviewMode", "aiReviewByok", "aiReviewProvider", "aiReviewModel", "aiReviewAllAuthors"] as const; // Settings fields that are DELIBERATELY absent from `.gittensory.yml.example` (unlike the gate-aliased fields // above, these are never documented anywhere in the public template): agentGlobalFreezeOverride is an @@ -1997,7 +1997,7 @@ describe("parseFocusManifest settings override + resolveEffectiveSettings", () = publicSignalLevel: "minimal", checkRunMode: "enabled", checkRunDetailLevel: "standard", - gateCheckMode: "enabled", + reviewCheckMode: "required", linkedIssueGateMode: "block", duplicatePrGateMode: "off", qualityGateMode: "advisory", @@ -2019,9 +2019,6 @@ describe("parseFocusManifest settings override + resolveEffectiveSettings", () = publicSignalLevel: "minimal", checkRunMode: "enabled", checkRunDetailLevel: "standard", - gateCheckMode: "enabled", - // #4618: gateCheckMode is deprecated -- setting it alone (no explicit reviewCheckMode) still derives - // reviewCheckMode, so its historical effect on the actual publish authority is preserved. reviewCheckMode: "required", linkedIssueGateMode: "block", duplicatePrGateMode: "off", @@ -2519,18 +2516,23 @@ describe("parseFocusManifest settings override + resolveEffectiveSettings", () = }); // #4618/#5373: the RepositorySettings.gateCheckMode field (a computed read-back of reviewCheckMode) was - // removed entirely in #5373 -- resolveEffectiveSettings no longer derives or exposes it. The yml - // settings.gateCheckMode key still parses at the gittensory-engine layer (back-compat, tracked separately - // for removal), always resolving to reviewCheckMode rather than being trusted as its own source of truth. - describe("settings.gateCheckMode back-compat parsing (#4618)", () => { - it("settings.gateCheckMode alone (no reviewCheckMode) derives reviewCheckMode, keeping its historical effect", () => { + // removed entirely in #5373, including the gittensory-engine yml-parsing layer's settings.gateCheckMode + // back-compat key (#5373 stage 2.10) -- it is now a fully unrecognized settings key, parsed into nothing + // and deriving nothing. resolveEffectiveSettings no longer derives or exposes the field either. + describe("settings.gateCheckMode is a fully removed, inert key (#4618/#5373)", () => { + it("settings.gateCheckMode alone no longer derives reviewCheckMode (back-compat removed)", () => { const enabled = parseFocusManifest({ settings: { gateCheckMode: "enabled" } }); - expect(enabled.settings.reviewCheckMode).toBe("required"); + expect(enabled.settings.reviewCheckMode).toBeUndefined(); const off = parseFocusManifest({ settings: { gateCheckMode: "off" } }); - expect(off.settings.reviewCheckMode).toBe("disabled"); + expect(off.settings.reviewCheckMode).toBeUndefined(); }); - it("an explicit settings.reviewCheckMode wins over settings.gateCheckMode when both are set", () => { + it("settings.gateCheckMode is not parsed into the output settings object at all", () => { + const m = parseFocusManifest({ settings: { gateCheckMode: "enabled" } }); + expect(m.settings).not.toHaveProperty("gateCheckMode"); + }); + + it("an explicit settings.reviewCheckMode is honored regardless of a settings.gateCheckMode also present", () => { const m = parseFocusManifest({ settings: { gateCheckMode: "off", reviewCheckMode: "visible" } }); expect(m.settings.reviewCheckMode).toBe("visible"); }); diff --git a/test/unit/gate-check-policy.test.ts b/test/unit/gate-check-policy.test.ts index 893c30b82a..d48d8219dd 100644 --- a/test/unit/gate-check-policy.test.ts +++ b/test/unit/gate-check-policy.test.ts @@ -62,11 +62,11 @@ describe(".gittensory.yml settings override (resolveEffectiveSettings)", () => { it("overlays the generic settings: block over DB, and gate: wins for gate fields", () => { const eff = resolveEffectiveSettings( settings({ commentMode: "off", publicSurface: "off", reviewCheckMode: "disabled", linkedIssueGateMode: "off" }), - parseFocusManifest({ settings: { commentMode: "all_prs", publicSurface: "comment_only", gateCheckMode: "enabled", linkedIssueGateMode: "advisory" }, gate: { linkedIssue: "block" } }), + parseFocusManifest({ settings: { commentMode: "all_prs", publicSurface: "comment_only", reviewCheckMode: "required", linkedIssueGateMode: "advisory" }, gate: { linkedIssue: "block" } }), ); expect(eff.commentMode).toBe("all_prs"); // settings: override expect(eff.publicSurface).toBe("comment_only"); // settings: override - expect(eff.reviewCheckMode).toBe("required"); // settings.gateCheckMode: enabled -> reviewCheckMode: required (engine-level back-compat parse, #5373 stage 2.10) + expect(eff.reviewCheckMode).toBe("required"); // settings: override expect(eff.linkedIssueGateMode).toBe("block"); // gate: wins over settings: });