Skip to content

Reduce redundant config surface: linked-issue knob, gateCheckMode, label fields #4618

Description

@JSONbored

Context

Part of the review-stack architecture audit (parent epic — config-sprawl dimension). Three related
config-surface-reduction opportunities, bundled together since they share the same motivation:
RepositorySettings has grown to 102 top-level fields (src/types.ts:678-1099), pushing the
DB-backed surface to roughly 140 discrete settable values, plus another ~60-80 yml-only knobs in the
separate FocusManifest type — 200+ discrete knobs total. Reducing genuinely redundant surface area
directly benefits both current self-hosters (less to learn) and a future hosted multi-tenant version
(less for a per-tenant settings UI to render).

1. Three independent knobs for one logical setting ("require a linked issue")

  • settings.requireLinkedIssue: boolean (DB + dashboard + yml settings.requireLinkedIssue)
  • gate.linkedIssuelinkedIssueGateMode: off|advisory|block (DB + dashboard + yml)
  • top-level yml linkedIssuePolicy: required|preferred|optional (focus-manifest, config-as-code only)

src/signals/focus-manifest.ts:585-589 auto-promotes requireLinkedIssue: true +
linkedIssueGateMode: "off""block", but there is no cross-promotion with linkedIssuePolicy,
and the two feed genuinely different finding codes (missing_linked_issue vs
manifest_linked_issue_required, confirmed at focus-manifest.ts:683-701 and
src/signals/engine.ts:2561/2772). A self-hoster who sets linkedIssuePolicy: required (in the section
titled "FOCUS / GUARDRAILS") gets an advisory nudge but not a gate blocker — they'd have to
separately discover gate.linkedIssue: block exists too, in a completely different section of the same
file. Even src/signals/repo-policy-readiness.ts:109,120 has to cross-reference both.

Fix: fold linkedIssuePolicy into linkedIssueGateMode's promotion logic, or rename/relocate one of
them so their relationship is visible in the config file rather than only in code comments.

2. Redundant boolean+enum pair kept alive only for back-compat

gateCheckMode: "off"|"enabled" (src/types.ts:685) is a legacy shadow of
reviewCheckMode: "required"|"visible"|"disabled" (src/types.ts:697), the actual runtime authority
(its own doc comment: "gateCheckMode above stays wired for API/back-compat display but no longer drives
the publish decision on its own"). Both are separate DB columns (src/db/schema.ts:53), both appear in
4 places in src/openapi/schemas.ts, and src/api/routes.ts:2382-2383 needs explicit dual-write sync
code to keep them from diverging on a legacy-only write.

Fix: deprecate gateCheckMode from new writes/docs; keep only as a computed read-back property.

3. 13 near-identical "disable-this-label" fields

gittensorLabel, blacklistLabel, contributorCapLabel, reviewNagLabel, newAccountLabel,
moderationWarningLabel, moderationBannedLabel, manualReviewLabel, readyToMergeLabel,
changesRequestedLabel, migrationCollisionLabel, pendingClosureLabel, reviewEvasionLabel — 13
separate top-level fields, each independently string | null | undefined with the same "explicit null
disables the label, undefined uses a hardcoded default" idiom repeated verbatim 10+ times
(src/types.ts:920-1091). Real, working design (not a bug), but 13x the type-surface, 13x the DB
columns, 13x the OpenAPI entries, and 13x the yml documentation a single labels: Record<LabelKey, string | null> map would need.

Fix: collapse into one labels map, with a migration path for existing per-field DB values.

Acceptance criteria

  • Item 1: linkedIssuePolicy and linkedIssueGateMode produce consistent gate behavior, documented
    in one place.
  • Item 2: gateCheckMode is deprecated (read-only, derived from reviewCheckMode); dual-write sync
    code removed.
  • Item 3: 13 label fields collapsed into one map, with existing per-repo DB values migrated without
    data loss.
  • Each item may land as a separate PR given migration/back-compat considerations; full branch
    coverage on each.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

Status
In Progress

Relationships

None yet

Development

No branches or pull requests

Issue actions