Summary
Several call sites read repository settings via the raw getRepositorySettings(env, repoFullName) DB accessor instead of the manifest-aware resolveRepositorySettings(env, repoFullName) (src/settings/repository-settings.ts:34-45). The documented precedence — .gittensory.yml > per-repo dashboard/API settings (DB) > built-in safe defaults — is correctly enforced inside resolveRepositorySettings/resolveEffectiveSettings (src/signals/focus-manifest.ts:1552-1630), but these call sites bypass that resolver entirely, so a maintainer's .gittensory.yml override is silently ignored at exactly these code paths.
Part of #1667.
Context
Found during a 2026-07-04 self-host review-engine audit. The actual gate/action execution pipeline (src/services/agent-approval-queue.ts and friends) correctly uses resolveRepositorySettings, so this is not a systemic architecture problem — it's localized drift at a handful of call sites that were written against the raw DB accessor and never updated when the resolver became the canonical path.
Confirmed bypass call sites:
src/github/backfill.ts:375,449 — settings.backfillEnabled gates whether backfill runs at all. A repo setting backfillEnabled: false (or the gate:-block equivalent) in .gittensory.yml is not respected here.
src/github/backfill.ts:952,1150 — settings.checkRunMode/gateCheckMode/autonomy feed installation-permission-repair diagnostics using the raw DB row.
src/mcp/server.ts:2451-2460 — the getAutomationState MCP tool reads settings.autonomy, settings.agentPaused, settings.agentDryRun via raw getRepositorySettings. Its reported mode= and acting-action-class count can be stale/wrong for any repo whose .gittensory.yml sets these fields, even though the real action-execution path applies them correctly.
src/api/routes.ts:285 — loadPublicRepoBadge reads settings.badgeEnabled via raw getRepositorySettings.
src/api/routes.ts:4315,4367 and src/services/contributor-issue-draft.ts:505 — buildRegistrationReadinessResponse, buildGittensorConfigRecommendationResponse, and the contributor-issue-draft context builder are advisory/recommendation text builders reading the raw DB row.
Requirements
- For each call site, determine intent before changing it: some (e.g. a dashboard read-before-write endpoint that legitimately wants the persisted DB row, not a yml preview) may be correct as-is and should get a one-line comment explaining why, not a mechanical swap.
- Where the intent is "this should reflect
.gittensory.yml like everywhere else," switch the call site to resolveRepositorySettings/resolveEffectiveSettings and verify no caching/perf assumption breaks (the MCP tool path in particular should be checked for whether an async resolver call fits its existing call pattern).
- Do not change the resolver itself unless a genuine bug is found in it — this issue is about bringing outlying call sites in line with the resolver's already-correct precedence logic, not re-deriving precedence.
Deliverables
- A PR (or a small number of PRs, one per logically distinct call site if they carry different risk) that either migrates each bypass to
resolveRepositorySettings or documents in-code why it intentionally reads the raw DB row.
- Regression tests proving a
.gittensory.yml-set value now takes effect at each migrated call site (e.g. backfillEnabled: false in the manifest actually skips backfill; getAutomationState reflects a yml-set autonomy override).
- No change in behavior for any call site confirmed to be an intentional exception.
Expected outcome
Every settings read in the codebase either goes through the resolver (and therefore honors the documented .gittensory.yml > DB > defaults precedence) or has an explicit, reviewed rationale for why it doesn't. A self-hoster's .gittensory.yml override is never silently ignored by an internal diagnostic or admission check.
Summary
Several call sites read repository settings via the raw
getRepositorySettings(env, repoFullName)DB accessor instead of the manifest-awareresolveRepositorySettings(env, repoFullName)(src/settings/repository-settings.ts:34-45). The documented precedence —.gittensory.yml> per-repo dashboard/API settings (DB) > built-in safe defaults — is correctly enforced insideresolveRepositorySettings/resolveEffectiveSettings(src/signals/focus-manifest.ts:1552-1630), but these call sites bypass that resolver entirely, so a maintainer's.gittensory.ymloverride is silently ignored at exactly these code paths.Part of #1667.
Context
Found during a 2026-07-04 self-host review-engine audit. The actual gate/action execution pipeline (
src/services/agent-approval-queue.tsand friends) correctly usesresolveRepositorySettings, so this is not a systemic architecture problem — it's localized drift at a handful of call sites that were written against the raw DB accessor and never updated when the resolver became the canonical path.Confirmed bypass call sites:
src/github/backfill.ts:375,449—settings.backfillEnabledgates whether backfill runs at all. A repo settingbackfillEnabled: false(or thegate:-block equivalent) in.gittensory.ymlis not respected here.src/github/backfill.ts:952,1150—settings.checkRunMode/gateCheckMode/autonomyfeed installation-permission-repair diagnostics using the raw DB row.src/mcp/server.ts:2451-2460— thegetAutomationStateMCP tool readssettings.autonomy,settings.agentPaused,settings.agentDryRunvia rawgetRepositorySettings. Its reportedmode=and acting-action-class count can be stale/wrong for any repo whose.gittensory.ymlsets these fields, even though the real action-execution path applies them correctly.src/api/routes.ts:285—loadPublicRepoBadgereadssettings.badgeEnabledvia rawgetRepositorySettings.src/api/routes.ts:4315,4367andsrc/services/contributor-issue-draft.ts:505—buildRegistrationReadinessResponse,buildGittensorConfigRecommendationResponse, and the contributor-issue-draft context builder are advisory/recommendation text builders reading the raw DB row.Requirements
.gittensory.ymllike everywhere else," switch the call site toresolveRepositorySettings/resolveEffectiveSettingsand verify no caching/perf assumption breaks (the MCP tool path in particular should be checked for whether an async resolver call fits its existing call pattern).Deliverables
resolveRepositorySettingsor documents in-code why it intentionally reads the raw DB row..gittensory.yml-set value now takes effect at each migrated call site (e.g.backfillEnabled: falsein the manifest actually skips backfill;getAutomationStatereflects a yml-setautonomyoverride).Expected outcome
Every settings read in the codebase either goes through the resolver (and therefore honors the documented
.gittensory.yml> DB > defaults precedence) or has an explicit, reviewed rationale for why it doesn't. A self-hoster's.gittensory.ymloverride is never silently ignored by an internal diagnostic or admission check.