Skip to content

Unify per-feature *-wire.ts activation behind one shared resolver #4616

Description

@JSONbored

Context

Part of the review-stack architecture audit (parent epic — config-sprawl dimension). This is the
single highest-impact finding in the config-sprawl audit
— it has already caused a real production
incident and directly blocks the "reuse the existing config plumbing for a future hosted version" goal.

The problem

There isn't one config-resolution system for advisory review capabilities; there are at least five,
independently implemented, with different precedence per feature.

The "canonical" path is resolveRepositorySettings (src/settings/repository-settings.ts:34) →
resolveEffectiveSettings (src/signals/focus-manifest.ts:496), which correctly implements
.gittensory.yml > DB > defaults for the 102 fields of RepositorySettings. That part is solid.

But a family of ~16 src/review/*-wire.ts modules gate advisory review capabilities (RAG, reputation,
unified comment, safety defang, grounding, e2e-test-gen, screenshots, inline comments, fix-handoff,
impact map, culture profile, review memory, content lane, selftune, …) through their own, separately-
coded
activation logic that sits entirely outside RepositorySettings/resolveEffectiveSettings. At
least four distinct precedence shapes exist:

  • Shared function resolveConvergedFeature (src/review/feature-activation.ts:48) for 6 features
    (rag/reputation/unifiedComment/safety/grounding/e2eTests): env kill-switch AND (yml features.X
    override OR GITTENSORY_REVIEW_REPOS allowlist fallback), with safety/grounding asymmetrically
    clamped.
  • src/review/visual-wire.ts:24 (screenshots): env flag AND allowlist onlyscreenshots is
    not even a ConvergedFeatureKey, so it has no .gittensory.yml features: override at all, unlike
    its 6 siblings documented right next to it in .gittensory.yml.example:1092-1098.
  • src/review/impact-map-wire.ts, review-memory-wire.ts, repo-culture-profile-wire.ts: env flag
    AND a .gittensory.yml review.X toggle only — no allowlist role whatsoever.
  • src/review/inline-comments.ts:43, fix-handoff.ts: env flag AND explicit yml toggle only, with
    comments explicitly noting the allowlist "no longer applies to this feature" — a documented behavior
    change from an earlier, different precedence.

A self-hoster who sets review.impact_map: true has no way to know they also need
GITTENSORY_REVIEW_IMPACT_MAP=true set at the deployment level, while a self-hoster who sets
features.screenshots: true (a natural guess given the six sibling keys right there in the example)
will find it silently does nothing, because screenshots activation is env+allowlist only. Each
-wire.ts file documents its own rule accurately in isolation, but there is no single place that tells
an operator "here is the one true way every feature gets turned on."

Already caused a real incident

src/env.d.ts:376-386 documents that GITTENSORY_REVIEW_REPOS and GITTENSORY_PUBLIC_STATS_REPOS
"once held the same value," and a past reuse of the review cutover allowlist for the public stats
allowlist meant that correctly emptying GITTENSORY_REVIEW_REPOS (after those repos moved to self-host)
silently zeroed the unrelated public homepage counter too.

Fix

Consolidate the *-wire.ts activation checks behind one shared resolver — extend
resolveConvergedFeature to cover all per-PR advisory features, including
screenshots/impact-map/memory/culture-profile/inline-comments/fix-handoff, with one documented
precedence rule and named, per-feature exceptions only where security actually requires asymmetry
(safety/grounding already show this is doable).

Acceptance criteria

  • All ~16 advisory-feature activation checks route through one shared resolver with one documented
    precedence rule.
  • Every feature in .gittensory.yml.example's features: block behaves identically re: what
    overrides what (yml vs env vs allowlist).
  • No behavior change for any repo's current effective feature set (verify against current production
    config before/after).
  • This is the flagship reuse target for a future hosted/multi-tenant version — design the shared
    resolver so per-tenant config could plug in without a second rewrite.

Given the size (16 call sites across distinct features), expect multiple sequential PRs.

Metadata

Metadata

Assignees

Labels

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

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions