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
20 changes: 12 additions & 8 deletions .gittensory.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -1102,21 +1102,25 @@ 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/grounding/e2eTests). 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. `e2eTests` (#4190) is a plain symmetric override
# like rag/reputation/unifiedComment -- generating AI test content carries no security-hardening rationale to
# protect from a repo-controlled override, so there's no force-on/force-off asymmetry here.
# GITTENSORY_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety/grounding/e2eTests/improvementSignal).
# 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. `e2eTests` (#4190) and `improvementSignal` (#4738,
# foundation phase of the #4737 PR-improvement-signal epic) are plain symmetric overrides like
# rag/reputation/unifiedComment -- neither AI-generated test content nor a read-only advisory quality-delta
# signal carries a security-hardening rationale to protect from a repo-controlled override, so there's no
# force-on/force-off asymmetry for either. `improvementSignal` is activation wiring only for now -- no tier
# reads the resolved value yet.
# features:
# rag: true
# reputation: false
# unifiedComment: true
# safety: true
# grounding: true
# e2eTests: false
# improvementSignal: false

# 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
1 change: 1 addition & 0 deletions apps/gittensory-ui/src/routes/docs.privacy-security.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ GITTENSORY_REVIEW_FIX_HANDOFF="true" # machine-readable fix-handoff
GITTENSORY_REVIEW_PLANNER="true" # @gittensory plan on-demand implementation plan
GITTENSORY_REVIEW_SCREENSHOTS="true" # before/after visual capture for UI changes
GITTENSORY_REVIEW_E2E_TESTS="true" # AI-generated E2E test coverage (needs features.e2eTests too)
GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL="true" # read-only PR quality-delta signal (activation only, no-op for now)

# Global (cron / endpoint) flags, not scoped by GITTENSORY_REVIEW_REPOS.
GITTENSORY_REVIEW_CONTINUOUS="true" # fleet-wide default: re-review on every push (else one-shot)
Expand Down
7 changes: 7 additions & 0 deletions apps/gittensory-ui/src/routes/docs.tuning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ function Tuning() {
needs its own <code>features.e2eTests: true</code> override in{" "}
<code>.gittensory.yml</code> before the feature is active for it. Per-PR.
</li>
<li>
<code>GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL</code> — master kill-switch for the read-only,
advisory PR quality-delta signal (the positive-axis counterpart to the slop risk score).
Off by default; config-as-code activation only for now — no tier reads the resolved value
yet, so turning this on has no visible effect until a later release wires real behavior
behind it. Per-PR.
</li>
<li>
<code>GITTENSORY_REVIEW_CONTINUOUS</code> — fleet-wide default AI review re-trigger
cadence. Off by default (one-shot): AI-generated content (main review, slop advisory,
Expand Down
20 changes: 12 additions & 8 deletions config/examples/gittensory.full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1115,21 +1115,25 @@ 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/grounding/e2eTests). 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. `e2eTests` (#4190) is a plain symmetric override
# like rag/reputation/unifiedComment -- generating AI test content carries no security-hardening rationale to
# protect from a repo-controlled override, so there's no force-on/force-off asymmetry here.
# GITTENSORY_REVIEW_* env kill-switch (rag/reputation/unifiedComment/safety/grounding/e2eTests/improvementSignal).
# 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. `e2eTests` (#4190) and `improvementSignal` (#4738,
# foundation phase of the #4737 PR-improvement-signal epic) are plain symmetric overrides like
# rag/reputation/unifiedComment -- neither AI-generated test content nor a read-only advisory quality-delta
# signal carries a security-hardening rationale to protect from a repo-controlled override, so there's no
# force-on/force-off asymmetry for either. `improvementSignal` is activation wiring only for now -- no tier
# reads the resolved value yet.
# features:
# rag: true
# reputation: false
# unifiedComment: true
# safety: true
# grounding: true
# e2eTests: false
# improvementSignal: false

# 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
9 changes: 7 additions & 2 deletions packages/gittensory-engine/src/focus-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,12 @@ export type CopycatGateMode = "off" | "warn" | "label" | "block";
// `review/selftune-wire.ts`. `e2eTests` (#4190, part of the #4189 E2E-test-generation epic) fits this shape
// exactly as a plain symmetric override — unlike `safety`/`grounding` it has no force-on-only or force-off-only
// floor/ceiling, since AI-generated test content carries no security-hardening or full-file-fetch rationale to
// protect from a repo-controlled override.
export const CONVERGED_FEATURE_KEYS = ["rag", "reputation", "unifiedComment", "safety", "grounding", "e2eTests"] as const;
// protect from a repo-controlled override. `improvementSignal` (#4738, foundation phase of the #4737 PR-
// improvement-signal epic) is likewise a plain symmetric override: it is a READ-ONLY advisory quality-delta
// signal, not a security control, so a repo-level `false` behaves like any other plain override with no
// floor/ceiling. This is activation wiring only -- no tier reads the resolved value yet (sibling sub-issues
// #4739-#4746 build the deterministic/LLM/panel behavior that will gate on it).
export const CONVERGED_FEATURE_KEYS = ["rag", "reputation", "unifiedComment", "safety", "grounding", "e2eTests", "improvementSignal"] 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 @@ -963,6 +967,7 @@ const EMPTY_FEATURES_CONFIG: FocusManifestFeaturesConfig = {
safety: null,
grounding: null,
e2eTests: null,
improvementSignal: null,
};

const EMPTY_CONTENT_LANE_CONFIG: FocusManifestContentLaneConfig = {
Expand Down
6 changes: 6 additions & 0 deletions src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ declare global {
* E2E test coverage feature. Default OFF — unset/false the feature is never active for any repo regardless
* of a per-repo `features.e2eTests` override. */
GITTENSORY_REVIEW_E2E_TESTS?: string;
/** Convergence (improvementSignal, #4738, foundation phase of the #4737 epic): master kill-switch for the
* read-only, ADVISORY PR quality-delta signal (the positive-axis counterpart to slop.ts's risk score).
* This is config-as-code activation ONLY — no tier reads this flag yet; sibling sub-issues (#4739-#4746)
* build the deterministic/LLM/panel behavior that will gate on it. Default OFF — unset/false the feature
* is never active for any repo regardless of a per-repo `features.improvementSignal` override. */
GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL?: string;
/** #one-shot-review-cadence: the operator's FLEET-WIDE default for AI review re-trigger cadence, consulted
* only when a repo's `.gittensory.yml review.auto_review.cadence` is unset (a per-repo value always wins
* regardless of this flag — see resolveAiReviewCadence). Default OFF (unset/false) ⇒ "one_shot": the
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 @@ -21,6 +21,7 @@
import { isConvergenceRepoAllowed } from "./cutover-gate";
import { isE2eTestGenerationEnabled } from "./e2e-test-gen-wire";
import { isGroundingEnabled } from "./grounding-wire";
import { isImprovementSignalEnabled } from "./improvement-signal-wire";
import { isRagEnabled } from "./rag-wire";
import { isReputationEnabled } from "./reputation-wire";
import { isSafetyEnabled } from "./safety";
Expand All @@ -36,6 +37,7 @@ const FEATURE_GLOBAL_FLAG: Record<ConvergedFeatureKey, (env: Env) => boolean> =
safety: isSafetyEnabled,
grounding: isGroundingEnabled,
e2eTests: isE2eTestGenerationEnabled,
improvementSignal: isImprovementSignalEnabled,
};

/**
Expand Down
19 changes: 19 additions & 0 deletions src/review/improvement-signal-wire.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Convergence (PR improvement signal, #4738, foundation phase of the #4737 epic): the master kill-switch for the
// `improvementSignal` converged feature -- a read-only, ADVISORY quality-delta signal that is the positive-axis
// counterpart to src/signals/slop.ts's risk-only score (see #4737 for the full design). This file is deliberately
// minimal for now (just the env flag), mirroring the shape of `e2e-test-gen-wire.ts`/`rag-wire.ts` at the same
// stage of their own rollout -- the deterministic (REES) tier, the LLM tier, and panel surfacing land in later,
// separate sub-issues (#4739-#4746) once this flag exists for them to gate on. This PR wires activation only:
// nothing calls resolveConvergedFeature(env, manifest, "improvementSignal", repoFullName) yet outside this
// feature's own tests.
//
// Single env switch: GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL. Default OFF (unset/"false") -- when OFF the feature
// never runs anywhere, regardless of any per-repo `.gittensory.yml` override (see `resolveConvergedFeature` in
// `./feature-activation`). Truthy follows the codebase convention (`/^(1|true|yes|on)$/i`, same as
// isRagEnabled / isE2eTestGenerationEnabled).

/** True when the PR improvement signal is enabled at the deployment level. Flag-OFF (default) → the feature is
* never active for any repo, regardless of a per-repo `features.improvementSignal` override. */
export function isImprovementSignalEnabled(env: { GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL?: string | undefined }): boolean {
return /^(1|true|yes|on)$/i.test(env.GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL ?? "");
}
31 changes: 31 additions & 0 deletions test/unit/feature-activation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const FLAG: Record<ConvergedFeatureKey, string> = {
safety: "GITTENSORY_REVIEW_SAFETY",
grounding: "GITTENSORY_REVIEW_GROUNDING",
e2eTests: "GITTENSORY_REVIEW_E2E_TESTS",
improvementSignal: "GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL",
};

function env(overrides: Record<string, string | undefined>): Env {
Expand All @@ -28,6 +29,7 @@ function manifestWith(features: Partial<Record<ConvergedFeatureKey, boolean>>):
safety: null,
grounding: null,
e2eTests: null,
improvementSignal: null,
} as FocusManifest["features"];
return { features: { ...base, ...features, present: Object.keys(features).length > 0 } };
}
Expand Down Expand Up @@ -103,6 +105,35 @@ describe("resolveConvergedFeature — grounding remains allowlist-bound", () =>
});
});

describe("resolveConvergedFeature — improvementSignal is a plain symmetric override (#4738)", () => {
// The full resolution matrix the #4738 acceptance criteria calls out explicitly: env off; env on + no
// override; env on + repo true; env on + repo false. improvementSignal has no safety/grounding-style
// asymmetry, so this mirrors the generic "standard mode" shape rag/reputation/unifiedComment/e2eTests use.
it("is off when the global env flag is off, regardless of a per-repo override or the allowlist (env off)", () => {
const e = env({ GITTENSORY_REVIEW_REPOS: REPO }); // GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL unset
expect(resolveConvergedFeature(e, manifestWith({ improvementSignal: true }), "improvementSignal", REPO)).toBe(false);
});

it("falls back to the GITTENSORY_REVIEW_REPOS allowlist when the flag is on but the manifest sets nothing (env on + no override)", () => {
const allowlisted = env({ GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: "true", GITTENSORY_REVIEW_REPOS: REPO });
expect(resolveConvergedFeature(allowlisted, manifestWith({}), "improvementSignal", REPO)).toBe(true);
expect(resolveConvergedFeature(allowlisted, null, "improvementSignal", REPO)).toBe(true); // null manifest tolerated

const notAllowlisted = env({ GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: "true", GITTENSORY_REVIEW_REPOS: "other/repo" });
expect(resolveConvergedFeature(notAllowlisted, manifestWith({}), "improvementSignal", REPO)).toBe(false);
});

it("honors an explicit per-repo override of true even when the repo is NOT allowlisted (env on + repo true)", () => {
const e = env({ GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: "true", GITTENSORY_REVIEW_REPOS: "other/repo" });
expect(resolveConvergedFeature(e, manifestWith({ improvementSignal: true }), "improvementSignal", REPO)).toBe(true);
});

it("honors an explicit per-repo override of false even when the repo IS allowlisted (env on + repo false)", () => {
const e = env({ GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: "true", GITTENSORY_REVIEW_REPOS: REPO });
expect(resolveConvergedFeature(e, manifestWith({ improvementSignal: false }), "improvementSignal", REPO)).toBe(false);
});
});

describe("convergedFeatureActive — async (loads the cached manifest)", () => {
it("short-circuits to false WITHOUT loading the manifest when the env flag is off", async () => {
// DB-less env: if it tried to load the manifest it would throw; returning false proves the short-circuit.
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 @@ -415,6 +415,7 @@ describe(".gittensory.yml.example field-exhaustiveness (#1670)", () => {
safety: "safety:",
grounding: "grounding:",
e2eTests: "e2eTests:",
improvementSignal: "improvementSignal:",
} satisfies Record<Exclude<keyof FocusManifestFeaturesConfig, "present">, string>;

it.each(Object.entries(FEATURES_FIELD_TOKENS))("documents features.%s", (_field, token) => {
Expand Down Expand Up @@ -829,7 +830,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, aiReviewLowConfidenceDisposition: 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, aiJudgmentBlockersMode: null, copycatMode: null, copycatMinScore: 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, impactMap: null, cultureProfile: null, selftune: null, reviewMemory: null, findingCategories: null, inlineCommentsPerCategory: null, minFindingSeverity: null, maxFindings: { blockers: null, nits: null }, commentVerbosity: null, e2eTestDelivery: 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, grounding: null, e2eTests: null },
features: { present: false, rag: null, reputation: null, unifiedComment: null, safety: null, grounding: null, e2eTests: null, improvementSignal: 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
20 changes: 20 additions & 0 deletions test/unit/improvement-signal-wiring.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { describe, expect, it } from "vitest";
import { isImprovementSignalEnabled } from "../../src/review/improvement-signal-wire";

describe("isImprovementSignalEnabled — the improvementSignal converged-feature master kill-switch (#4738)", () => {
it("is off when the env flag is unset (the nullish fallback branch)", () => {
expect(isImprovementSignalEnabled({ GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: undefined })).toBe(false);
expect(isImprovementSignalEnabled({})).toBe(false);
});

it("is off for an explicit falsy-looking value", () => {
expect(isImprovementSignalEnabled({ GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: "false" })).toBe(false);
expect(isImprovementSignalEnabled({ GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: "0" })).toBe(false);
});

it("is on for every truthy-string spelling, case-insensitively (the present branch)", () => {
for (const value of ["1", "true", "TRUE", "yes", "YES", "on", "On"]) {
expect(isImprovementSignalEnabled({ GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: value })).toBe(true);
}
});
});
4 changes: 3 additions & 1 deletion worker-configuration.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types` (hash: 7eeadad15ce002765f06a319222e9f94)
// Generated by Wrangler by running `wrangler types` (hash: 7cd863ec781ed395e3f5eb00399370bc)
// Runtime types generated with workerd@1.20260701.1 2026-05-28 nodejs_compat
interface __BaseEnv_Env {
DB: D1Database;
Expand All @@ -23,6 +23,7 @@ interface __BaseEnv_Env {
GITTENSORY_REVIEW_SCREENSHOTS: "false";
GITTENSORY_REVIEW_GROUNDING: "false";
GITTENSORY_REVIEW_E2E_TESTS: "false";
GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL: "false";
GITTENSORY_REVIEW_CONTINUOUS: "false";
GITTENSORY_REVIEW_REPUTATION: "false";
GITTENSORY_REVIEW_OPS: "false";
Expand Down Expand Up @@ -83,6 +84,7 @@ declare namespace NodeJS {
| "GITTENSORY_REVIEW_E2E_TESTS"
| "GITTENSORY_REVIEW_GROUNDING"
| "GITTENSORY_REVIEW_IMPACT_MAP"
| "GITTENSORY_REVIEW_IMPROVEMENT_SIGNAL"
| "GITTENSORY_REVIEW_INLINE_COMMENTS"
| "GITTENSORY_REVIEW_MEMORY"
| "GITTENSORY_REVIEW_OPS"
Expand Down
Loading
Loading