Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .gittensory.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -1005,14 +1005,18 @@ settings:
# auto_pause_after_reviewed_commits: 3

# Per-repo activation overrides for the converged review features that ship behind a deployment-wide
# GITTENSORY_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety). Each key is `true` (force on
# for this repo, subject to the env flag still being enabled), `false` (force off), or omitted (falls back
# to the GITTENSORY_REVIEW_REPOS allowlist default -- an operator who sets nothing keeps today's behavior).
# GITTENSORY_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety/grounding). Each key is `true`
# (force on for this repo, subject to the env flag still being enabled), `false` (force off), or omitted
# (falls back to the GITTENSORY_REVIEW_REPOS allowlist default -- an operator who sets nothing keeps today's
# behavior). Exception: `safety` is force-on-only -- an untrusted repo-controlled `false` is treated as "no
# opinion" rather than an active force-off (#2269), since a lower-trust actor must never be able to silently
# defeat the operator's own security-hardening enablement.
# features:
# rag: true
# reputation: false
# unifiedComment: true
# safety: true
# grounding: true

# Registry-review lane (#2435): lets a self-hosted maintainer point gittensory at their OWN structured
# registry (e.g. a subnet/plugin/package catalog) without a gittensory code change -- reviewing additions
Expand Down
10 changes: 7 additions & 3 deletions config/examples/gittensory.full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1018,14 +1018,18 @@ settings:
# auto_pause_after_reviewed_commits: 3

# Per-repo activation overrides for the converged review features that ship behind a deployment-wide
# GITTENSORY_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety). Each key is `true` (force on
# for this repo, subject to the env flag still being enabled), `false` (force off), or omitted (falls back
# to the GITTENSORY_REVIEW_REPOS allowlist default -- an operator who sets nothing keeps today's behavior).
# GITTENSORY_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety/grounding). Each key is `true`
# (force on for this repo, subject to the env flag still being enabled), `false` (force off), or omitted
# (falls back to the GITTENSORY_REVIEW_REPOS allowlist default -- an operator who sets nothing keeps today's
# behavior). Exception: `safety` is force-on-only -- an untrusted repo-controlled `false` is treated as "no
# opinion" rather than an active force-off (#2269), since a lower-trust actor must never be able to silently
# defeat the operator's own security-hardening enablement.
# features:
# rag: true
# reputation: false
# unifiedComment: true
# safety: true
# grounding: true

# Registry-review lane (#2435): lets a self-hosted maintainer point gittensory at their OWN structured
# registry (e.g. a subnet/plugin/package catalog) without a gittensory code change -- reviewing additions
Expand Down
16 changes: 10 additions & 6 deletions packages/gittensory-engine/src/focus-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,15 @@ export type FocusManifestGateConfig = {
// `.gittensory.yml`. Each feature ALSO has a GLOBAL env flag (GITTENSORY_REVIEW_*) that stays a master
// kill-switch (the feature never runs when its env flag is off, regardless of this block). See
// review/feature-activation.ts for the resolver (env kill-switch → per-repo override → env-allowlist default).
// NOTE: only the per-PR REVIEW features whose every activation site is migrated are listed here. grounding and
// screenshots stay on the GITTENSORY_REVIEW_REPOS allowlist for now (grounding is coupled to the merge/close
// DISPOSITION path; screenshots' capture path needs dedicated coverage) — a follow-up. contentLane got its own
// richer `contentLane:` block below (#2435) instead of a boolean here, since it resolves to a whole
// RegistryLaneSpec, not an on/off toggle — see resolveRegistryLaneSpec in review/content-lane/spec-resolver.ts.
export const CONVERGED_FEATURE_KEYS = ["rag", "reputation", "unifiedComment", "safety"] as const;
// NOTE: only the per-PR REVIEW features whose every activation site is migrated are listed here. grounding
// (#4100) is now migrated too — its original "coupled to the merge/close DISPOSITION path" blocker was the
// removed AI CI-refutation path (grounding-wire.ts's aiCiRefutationActive is now a vestigial historical-
// compatibility helper with zero real callers); grounding today only shapes reviewer PROMPT content, same
// shape as rag/reputation. `screenshots` has its own richer `visual:` block instead (review.visual.enabled,
// #4083) since it carries more than a single boolean. contentLane got its own richer `contentLane:` block below
// (#2435) instead of a boolean here, since it resolves to a whole RegistryLaneSpec, not an on/off toggle — see
// resolveRegistryLaneSpec in review/content-lane/spec-resolver.ts.
export const CONVERGED_FEATURE_KEYS = ["rag", "reputation", "unifiedComment", "safety", "grounding"] as const;
export type ConvergedFeatureKey = (typeof CONVERGED_FEATURE_KEYS)[number];

/** Per-repo activation overrides for the converged review features (`features:` block). `true`/`false` force the
Expand Down Expand Up @@ -826,6 +829,7 @@ const EMPTY_FEATURES_CONFIG: FocusManifestFeaturesConfig = {
reputation: null,
unifiedComment: null,
safety: null,
grounding: null,
};

const EMPTY_CONTENT_LANE_CONFIG: FocusManifestContentLaneConfig = {
Expand Down
31 changes: 19 additions & 12 deletions src/queue/processors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6999,13 +6999,13 @@ export async function runAiReviewForAdvisory(
// feature's global flag below. Empty/unset allowlist → false → every converged branch here is unreachable
// (byte-identical to today) regardless of the global flags.
const convergedRepoAllowed = isConvergenceRepoAllowed(env, args.repoFullName);
// Per-repo feature overrides (phase 2): reputation + RAG honor the container-private `.gittensory.yml` `features:`
// block, falling back to the `convergedRepoAllowed` allowlist when unset (byte-identical default). The (cached)
// manifest is loaded once and shared, and ONLY when at least one of the two features is globally enabled — so a
// deploy with both flags off does no extra read (preserves the no-op default). Grounding deliberately stays on
// `convergedRepoAllowed` here so prompt grounding remains tied to the converged review allowlist.
// Per-repo feature overrides (phase 2): reputation + RAG + grounding (#4100) honor the container-private
// `.gittensory.yml` `features:` block, falling back to the `convergedRepoAllowed` allowlist when unset
// (byte-identical default). The (cached) manifest is loaded once and shared, and ONLY when at least one of the
// three features is globally enabled — so a deploy with all three flags off does no extra read (preserves the
// no-op default).
const featureManifest =
isReputationEnabled(env) || isRagEnabled(env)
isReputationEnabled(env) || isRagEnabled(env) || isGroundingEnabled(env)
? await loadRepoFocusManifest(env, args.repoFullName).catch(() => null)
: null;
const reputationActive = resolveConvergedFeature(
Expand All @@ -7020,6 +7020,12 @@ export async function runAiReviewForAdvisory(
"rag",
args.repoFullName,
);
const groundingActive = resolveConvergedFeature(
env,
featureManifest,
"grounding",
args.repoFullName,
);
// Reputation anti-abuse (convergence, flag-gated by GITTENSORY_REVIEW_REPUTATION). Extends the AI-spend gate above:
// an INTERNAL low-reputation / burst / new submitter is downgraded to a DETERMINISTIC-ONLY review — the
// (paid) AI neurons are skipped here exactly as they are for an unconfirmed contributor, so a serial abuser
Expand Down Expand Up @@ -7088,12 +7094,13 @@ export async function runAiReviewForAdvisory(
args.settings.aiReviewMode === "block"
? allFiles
: filterReviewFilesForAi(allFiles, args.reviewExcludePaths ?? [], args.reviewPathFilters ?? []);
// Grounding (convergence, flag-gated by GITTENSORY_REVIEW_GROUNDING). Build the FINISHED CI status + the full
// content of the changed files so the reviewer verifies its claims against reality instead of guessing.
// Flag-OFF (default) → we take no new branch at all: NO check/repo load, NO file fetch, and `grounding`
// is left undefined so the prompt handed to the model is byte-identical to today. Fully fail-safe.
// Grounding (convergence, flag-gated by GITTENSORY_REVIEW_GROUNDING; per-repo `features.grounding` override,
// #4100). Build the FINISHED CI status + the full content of the changed files so the reviewer verifies its
// claims against reality instead of guessing. Flag-OFF (default) → we take no new branch at all: NO
// check/repo load, NO file fetch, and `grounding` is left undefined so the prompt handed to the model is
// byte-identical to today. Fully fail-safe.
const grounding =
isGroundingEnabled(env) && convergedRepoAllowed
groundingActive
? await buildReviewGroundingText(env, {
repoFullName: args.repoFullName,
headSha: args.advisory.headSha,
Expand Down Expand Up @@ -9273,7 +9280,7 @@ async function maybePublishPrPublicSurface(
// without fetching the content itself (which would defeat caching), so a repo with ANY of these active
// bypasses the cache entirely rather than fingerprinting a value that can't prove freshness.
const dynamicReviewFeatures = {
grounding: isGroundingEnabled(env) && convergedRepoAllowed,
grounding: resolveConvergedFeature(env, reviewManifest, "grounding", repoFullName),
rag: resolveConvergedFeature(env, reviewManifest, "rag", repoFullName),
enrichment: isEnrichmentEnabled(env) && convergedRepoAllowed,
reputation: resolveConvergedFeature(
Expand Down
2 changes: 2 additions & 0 deletions src/review/feature-activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// `resolveConvergedFeature` is the pure core (takes the already-loaded manifest). `convergedFeatureActive` is the
// async convenience that loads the cached focus manifest itself — used at call sites that don't already hold one.
import { isConvergenceRepoAllowed } from "./cutover-gate";
import { isGroundingEnabled } from "./grounding-wire";
import { isRagEnabled } from "./rag-wire";
import { isReputationEnabled } from "./reputation-wire";
import { isSafetyEnabled } from "./safety";
Expand All @@ -30,6 +31,7 @@ const FEATURE_GLOBAL_FLAG: Record<ConvergedFeatureKey, (env: Env) => boolean> =
reputation: isReputationEnabled,
unifiedComment: isUnifiedReviewCommentEnabled,
safety: isSafetyEnabled,
grounding: isGroundingEnabled,
};

/**
Expand Down
3 changes: 2 additions & 1 deletion test/unit/feature-activation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ const FLAG: Record<ConvergedFeatureKey, string> = {
reputation: "GITTENSORY_REVIEW_REPUTATION",
unifiedComment: "GITTENSORY_REVIEW_UNIFIED_COMMENT",
safety: "GITTENSORY_REVIEW_SAFETY",
grounding: "GITTENSORY_REVIEW_GROUNDING",
};

function env(overrides: Record<string, string | undefined>): Env {
return overrides as unknown as Env;
}
function manifestWith(features: Partial<Record<ConvergedFeatureKey, boolean>>): Pick<FocusManifest, "features"> {
const base = { present: false, rag: null, reputation: null, unifiedComment: null, safety: null } as FocusManifest["features"];
const base = { present: false, rag: null, reputation: null, unifiedComment: null, safety: null, grounding: null } as FocusManifest["features"];
return { features: { ...base, ...features, present: Object.keys(features).length > 0 } };
}

Expand Down
3 changes: 2 additions & 1 deletion test/unit/focus-manifest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ describe(".gittensory.yml.example field-exhaustiveness (#1670)", () => {
reputation: "reputation:",
unifiedComment: "unifiedComment:",
safety: "safety:",
grounding: "grounding:",
} satisfies Record<Exclude<keyof FocusManifestFeaturesConfig, "present">, string>;

it.each(Object.entries(FEATURES_FIELD_TOKENS))("documents features.%s", (_field, token) => {
Expand Down Expand Up @@ -801,7 +802,7 @@ describe("compileFocusManifestPolicy", () => {
gate: { present: false, enabled: null, checkMode: null, pack: null, linkedIssue: null, duplicates: null, readinessMode: null, readinessMinScore: null, slopMode: null, slopMinScore: null, slopAiAdvisory: null, sizeMode: null, lockfileIntegrityMode: null, aiReviewMode: null, aiReviewByok: null, aiReviewProvider: null, aiReviewModel: null, aiReviewAllAuthors: null, aiReviewCloseConfidence: null, aiReviewCombine: null, aiReviewOnMerge: null, aiReviewReviewers: null, mergeReadiness: null, selfAuthoredLinkedIssue: null, linkedIssueSatisfaction: null, manifestPolicy: null, dryRun: null, firstTimeContributorGrace: null, premergeContentRecheck: null, requireFreshRebaseWindowMinutes: null, claMode: null, claConsentPhrase: null, claCheckRunName: null, claCheckRunAppSlug: null, expectedCiContexts: null },
settings: {},
review: { present: false, footerText: null, note: null, fields: {}, enrichmentAnalyzers: {}, profile: null, tone: null, securityFocus: null, inlineComments: null, fixHandoff: null, autoMergeSummary: null, suggestions: null, changedFilesSummary: null, effortScore: null, testGeneration: null, impactMap: null, cultureProfile: null, reviewMemory: null, findingCategories: null, inlineCommentsPerCategory: null, minFindingSeverity: null, maxFindings: { blockers: null, nits: null }, commentVerbosity: null, pathInstructions: [], instructions: null, excludePaths: [], pathFilters: [], preMergeChecks: [], autoReview: { ...EMPTY_AUTO_REVIEW_CONFIG }, labelingRules: [], aiModel: { ...EMPTY_SELF_HOST_AI_MODEL_CONFIG }, visual: { ...EMPTY_VISUAL_CONFIG }, linkedIssueSatisfaction: null, sharedConfigSource: null },
features: { present: false, rag: null, reputation: null, unifiedComment: null, safety: null },
features: { present: false, rag: null, reputation: null, unifiedComment: null, safety: null, grounding: null },
contentLane: { present: false, entryFileGlob: null, providerFileGlob: null, artifactGlob: null, collectionField: null, maxAppendedEntries: null, duplicateKeyFields: [], validatorId: null },
repoDocGeneration: { present: false, enabled: false, scope: ["agents"], allowOverwriteExisting: false, refreshIntervalDays: 7 },
reviewRecap: { present: false, enabled: false, cadenceDays: 7 },
Expand Down