@loopover/engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/LICENSE +661 -0
- package/README.md +676 -0
- package/dist/advisory/gate-advisory.d.ts +151 -0
- package/dist/advisory/gate-advisory.js +512 -0
- package/dist/ai-policy-map.d.ts +97 -0
- package/dist/ai-policy-map.js +377 -0
- package/dist/ams-policy-spec.d.ts +56 -0
- package/dist/ams-policy-spec.js +165 -0
- package/dist/calibration-dashboard.d.ts +23 -0
- package/dist/calibration-dashboard.js +65 -0
- package/dist/calibration-trend.d.ts +40 -0
- package/dist/calibration-trend.js +60 -0
- package/dist/contributor-fit.d.ts +24 -0
- package/dist/contributor-fit.js +50 -0
- package/dist/discovery-index-contract.d.ts +74 -0
- package/dist/discovery-index-contract.js +184 -0
- package/dist/discovery-soft-claim.d.ts +35 -0
- package/dist/discovery-soft-claim.js +50 -0
- package/dist/duplicate-winner.d.ts +57 -0
- package/dist/duplicate-winner.js +98 -0
- package/dist/feasibility.d.ts +27 -0
- package/dist/feasibility.js +86 -0
- package/dist/finding-severity-calibration.d.ts +116 -0
- package/dist/finding-severity-calibration.js +457 -0
- package/dist/fleet-run-manifest.d.ts +41 -0
- package/dist/fleet-run-manifest.js +151 -0
- package/dist/focus-manifest/guidance.d.ts +21 -0
- package/dist/focus-manifest/guidance.js +222 -0
- package/dist/focus-manifest.d.ts +826 -0
- package/dist/focus-manifest.js +2730 -0
- package/dist/gate-verdict-calibration.d.ts +111 -0
- package/dist/gate-verdict-calibration.js +411 -0
- package/dist/github/constants.d.ts +1 -0
- package/dist/github/constants.js +1 -0
- package/dist/github/sanitize-public-comment.d.ts +1 -0
- package/dist/github/sanitize-public-comment.js +26 -0
- package/dist/goal-model.d.ts +7 -0
- package/dist/goal-model.js +87 -0
- package/dist/governor/action-mode.d.ts +55 -0
- package/dist/governor/action-mode.js +74 -0
- package/dist/governor/budget-cap.d.ts +49 -0
- package/dist/governor/budget-cap.js +34 -0
- package/dist/governor/chokepoint.d.ts +58 -0
- package/dist/governor/chokepoint.js +269 -0
- package/dist/governor/kill-switch.d.ts +38 -0
- package/dist/governor/kill-switch.js +62 -0
- package/dist/governor/rate-limit.d.ts +40 -0
- package/dist/governor/rate-limit.js +63 -0
- package/dist/governor/reputation-throttle.d.ts +50 -0
- package/dist/governor/reputation-throttle.js +94 -0
- package/dist/governor/run-halt.d.ts +39 -0
- package/dist/governor/run-halt.js +83 -0
- package/dist/governor/self-plagiarism.d.ts +47 -0
- package/dist/governor/self-plagiarism.js +200 -0
- package/dist/governor/write-rate-limit.d.ts +52 -0
- package/dist/governor/write-rate-limit.js +132 -0
- package/dist/governor-ledger.d.ts +25 -0
- package/dist/governor-ledger.js +91 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +120 -0
- package/dist/issue-plan-decomposition.d.ts +18 -0
- package/dist/issue-plan-decomposition.js +56 -0
- package/dist/issue-rag-query.d.ts +12 -0
- package/dist/issue-rag-query.js +35 -0
- package/dist/local-scorer.d.ts +34 -0
- package/dist/local-scorer.js +36 -0
- package/dist/metadata-best-min-score.d.ts +9 -0
- package/dist/metadata-best-min-score.js +9 -0
- package/dist/metadata-best-pick.d.ts +9 -0
- package/dist/metadata-best-pick.js +9 -0
- package/dist/metadata-min-score.d.ts +9 -0
- package/dist/metadata-min-score.js +13 -0
- package/dist/metadata-top-min-score.d.ts +9 -0
- package/dist/metadata-top-min-score.js +13 -0
- package/dist/metadata-top-pick.d.ts +9 -0
- package/dist/metadata-top-pick.js +13 -0
- package/dist/miner/acceptance-criteria.d.ts +43 -0
- package/dist/miner/acceptance-criteria.js +77 -0
- package/dist/miner/agent-sdk-driver.d.ts +39 -0
- package/dist/miner/agent-sdk-driver.js +162 -0
- package/dist/miner/attempt-log.d.ts +29 -0
- package/dist/miner/attempt-log.js +100 -0
- package/dist/miner/attempt-metering.d.ts +39 -0
- package/dist/miner/attempt-metering.js +67 -0
- package/dist/miner/cli-subprocess-driver.d.ts +68 -0
- package/dist/miner/cli-subprocess-driver.js +272 -0
- package/dist/miner/coding-agent-driver.d.ts +33 -0
- package/dist/miner/coding-agent-driver.js +36 -0
- package/dist/miner/coding-agent-invoke.d.ts +11 -0
- package/dist/miner/coding-agent-invoke.js +80 -0
- package/dist/miner/coding-agent-mode.d.ts +25 -0
- package/dist/miner/coding-agent-mode.js +43 -0
- package/dist/miner/driver-factory.d.ts +82 -0
- package/dist/miner/driver-factory.js +169 -0
- package/dist/miner/harness-submission-trigger.d.ts +37 -0
- package/dist/miner/harness-submission-trigger.js +46 -0
- package/dist/miner/iterate-loop.d.ts +97 -0
- package/dist/miner/iterate-loop.js +278 -0
- package/dist/miner/iterate-policy.d.ts +98 -0
- package/dist/miner/iterate-policy.js +98 -0
- package/dist/miner/lint-guard.d.ts +50 -0
- package/dist/miner/lint-guard.js +68 -0
- package/dist/miner/local-write-tools.d.ts +81 -0
- package/dist/miner/local-write-tools.js +113 -0
- package/dist/miner/loop-reentry-policy.d.ts +36 -0
- package/dist/miner/loop-reentry-policy.js +53 -0
- package/dist/miner/repo-map.d.ts +51 -0
- package/dist/miner/repo-map.js +268 -0
- package/dist/miner/self-review-adapter.d.ts +106 -0
- package/dist/miner/self-review-adapter.js +83 -0
- package/dist/miner/submission-gate.d.ts +40 -0
- package/dist/miner/submission-gate.js +89 -0
- package/dist/miner/worktree-allocator.d.ts +59 -0
- package/dist/miner/worktree-allocator.js +60 -0
- package/dist/miner/worktree-pool.d.ts +55 -0
- package/dist/miner/worktree-pool.js +65 -0
- package/dist/miner-goal-lane-fit.d.ts +18 -0
- package/dist/miner-goal-lane-fit.js +76 -0
- package/dist/miner-goal-spec.d.ts +139 -0
- package/dist/miner-goal-spec.js +281 -0
- package/dist/miner-prediction-metrics.d.ts +16 -0
- package/dist/miner-prediction-metrics.js +61 -0
- package/dist/miner-telemetry.d.ts +32 -0
- package/dist/miner-telemetry.js +87 -0
- package/dist/objective-anchor.d.ts +125 -0
- package/dist/objective-anchor.js +401 -0
- package/dist/opportunity-competition.d.ts +6 -0
- package/dist/opportunity-competition.js +29 -0
- package/dist/opportunity-freshness.d.ts +18 -0
- package/dist/opportunity-freshness.js +55 -0
- package/dist/opportunity-metadata.d.ts +53 -0
- package/dist/opportunity-metadata.js +204 -0
- package/dist/opportunity-ranker.d.ts +46 -0
- package/dist/opportunity-ranker.js +74 -0
- package/dist/pairwise-calibration.d.ts +49 -0
- package/dist/pairwise-calibration.js +106 -0
- package/dist/phase7-calibration-loop.d.ts +136 -0
- package/dist/phase7-calibration-loop.js +437 -0
- package/dist/plan-blocked.d.ts +6 -0
- package/dist/plan-blocked.js +24 -0
- package/dist/plan-completed.d.ts +5 -0
- package/dist/plan-completed.js +6 -0
- package/dist/plan-completion.d.ts +6 -0
- package/dist/plan-completion.js +7 -0
- package/dist/plan-empty.d.ts +5 -0
- package/dist/plan-empty.js +6 -0
- package/dist/plan-export.d.ts +27 -0
- package/dist/plan-export.js +86 -0
- package/dist/plan-failure.d.ts +5 -0
- package/dist/plan-failure.js +6 -0
- package/dist/plan-overall-status.d.ts +6 -0
- package/dist/plan-overall-status.js +25 -0
- package/dist/plan-pending.d.ts +5 -0
- package/dist/plan-pending.js +6 -0
- package/dist/plan-progress-complete.d.ts +7 -0
- package/dist/plan-progress-complete.js +10 -0
- package/dist/plan-ready.d.ts +6 -0
- package/dist/plan-ready.js +12 -0
- package/dist/plan-running.d.ts +5 -0
- package/dist/plan-running.js +6 -0
- package/dist/plan-skipped.d.ts +5 -0
- package/dist/plan-skipped.js +6 -0
- package/dist/plan-step-count.d.ts +5 -0
- package/dist/plan-step-count.js +6 -0
- package/dist/plan-step-stats.d.ts +5 -0
- package/dist/plan-step-stats.js +6 -0
- package/dist/plan-templates.d.ts +25 -0
- package/dist/plan-templates.js +107 -0
- package/dist/plan-terminated.d.ts +6 -0
- package/dist/plan-terminated.js +9 -0
- package/dist/portfolio/non-convergence.d.ts +37 -0
- package/dist/portfolio/non-convergence.js +57 -0
- package/dist/portfolio/queue.d.ts +30 -0
- package/dist/portfolio/queue.js +150 -0
- package/dist/predicted-gate.d.ts +103 -0
- package/dist/predicted-gate.js +218 -0
- package/dist/prompt-packet.d.ts +11 -0
- package/dist/prompt-packet.js +34 -0
- package/dist/ranked-opportunity-best-min-score.d.ts +8 -0
- package/dist/ranked-opportunity-best-min-score.js +9 -0
- package/dist/ranked-opportunity-best-pick.d.ts +8 -0
- package/dist/ranked-opportunity-best-pick.js +9 -0
- package/dist/ranked-opportunity-min-score.d.ts +8 -0
- package/dist/ranked-opportunity-min-score.js +13 -0
- package/dist/ranked-opportunity-top-min-score.d.ts +8 -0
- package/dist/ranked-opportunity-top-min-score.js +13 -0
- package/dist/review/advisory-ai-routing-config.d.ts +8 -0
- package/dist/review/advisory-ai-routing-config.js +40 -0
- package/dist/review/check-names.d.ts +1 -0
- package/dist/review/check-names.js +1 -0
- package/dist/review/cla-check.d.ts +49 -0
- package/dist/review/cla-check.js +71 -0
- package/dist/review/diff-file-priority.d.ts +1 -0
- package/dist/review/diff-file-priority.js +12 -0
- package/dist/review/enrichment-analyzer-names.d.ts +3 -0
- package/dist/review/enrichment-analyzer-names.js +63 -0
- package/dist/review/guardrail-config.d.ts +10 -0
- package/dist/review/guardrail-config.js +62 -0
- package/dist/review/linked-issue-hard-rules-config.d.ts +4 -0
- package/dist/review/linked-issue-hard-rules-config.js +79 -0
- package/dist/review/linked-issue-label-propagation.d.ts +9 -0
- package/dist/review/linked-issue-label-propagation.js +114 -0
- package/dist/review/pre-merge-checks.d.ts +28 -0
- package/dist/review/pre-merge-checks.js +66 -0
- package/dist/review/review-thread-findings.d.ts +1 -0
- package/dist/review/review-thread-findings.js +1 -0
- package/dist/review/safe-url.d.ts +5 -0
- package/dist/review/safe-url.js +137 -0
- package/dist/review/screenshot-table-gate.d.ts +87 -0
- package/dist/review/screenshot-table-gate.js +340 -0
- package/dist/review/unlinked-issue-guardrail-config.d.ts +9 -0
- package/dist/review/unlinked-issue-guardrail-config.js +44 -0
- package/dist/reviewer-consensus-calibration.d.ts +113 -0
- package/dist/reviewer-consensus-calibration.js +493 -0
- package/dist/reward-risk.d.ts +223 -0
- package/dist/reward-risk.js +618 -0
- package/dist/scoring/label-match.d.ts +4 -0
- package/dist/scoring/label-match.js +145 -0
- package/dist/scoring/model.d.ts +31 -0
- package/dist/scoring/model.js +157 -0
- package/dist/scoring/pending-pr-scenarios.d.ts +44 -0
- package/dist/scoring/pending-pr-scenarios.js +145 -0
- package/dist/scoring/preview.d.ts +246 -0
- package/dist/scoring/preview.js +1108 -0
- package/dist/scoring/types.d.ts +131 -0
- package/dist/scoring/types.js +7 -0
- package/dist/settings/auto-close-exempt.d.ts +10 -0
- package/dist/settings/auto-close-exempt.js +58 -0
- package/dist/settings/autonomy.d.ts +33 -0
- package/dist/settings/autonomy.js +80 -0
- package/dist/settings/command-authorization.d.ts +49 -0
- package/dist/settings/command-authorization.js +222 -0
- package/dist/settings/contributor-blacklist.d.ts +17 -0
- package/dist/settings/contributor-blacklist.js +86 -0
- package/dist/settings/moderation-rules.d.ts +51 -0
- package/dist/settings/moderation-rules.js +104 -0
- package/dist/settings/pr-type-label.d.ts +70 -0
- package/dist/settings/pr-type-label.js +149 -0
- package/dist/signals/change-guardrail.d.ts +49 -0
- package/dist/signals/change-guardrail.js +164 -0
- package/dist/signals/check-summary.d.ts +9 -0
- package/dist/signals/check-summary.js +12 -0
- package/dist/signals/contributor-calibration.d.ts +23 -0
- package/dist/signals/contributor-calibration.js +47 -0
- package/dist/signals/duplicate-winner.d.ts +9 -0
- package/dist/signals/duplicate-winner.js +9 -0
- package/dist/signals/path-matchers.d.ts +36 -0
- package/dist/signals/path-matchers.js +371 -0
- package/dist/signals/predicted-gate-engine.d.ts +62 -0
- package/dist/signals/predicted-gate-engine.js +895 -0
- package/dist/signals/preflight-limits.d.ts +14 -0
- package/dist/signals/preflight-limits.js +14 -0
- package/dist/signals/slop.d.ts +56 -0
- package/dist/signals/slop.js +324 -0
- package/dist/signals/test-evidence.d.ts +25 -0
- package/dist/signals/test-evidence.js +108 -0
- package/dist/subprocess-env.d.ts +23 -0
- package/dist/subprocess-env.js +74 -0
- package/dist/track-record-summary.d.ts +92 -0
- package/dist/track-record-summary.js +301 -0
- package/dist/types/manifest-deps-types.d.ts +514 -0
- package/dist/types/manifest-deps-types.js +4 -0
- package/dist/types/predicted-gate-types.d.ts +338 -0
- package/dist/types/predicted-gate-types.js +3 -0
- package/dist/types/reward-risk-types.d.ts +319 -0
- package/dist/types/reward-risk-types.js +11 -0
- package/dist/utils/json.d.ts +1 -0
- package/dist/utils/json.js +3 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +3 -0
- package/package.json +80 -0
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
export type { JsonValue } from "../scoring/types.js";
|
|
2
|
+
export type GateRuleMode = "off" | "advisory" | "block";
|
|
3
|
+
export type ReviewCheckMode = "required" | "visible" | "disabled";
|
|
4
|
+
export type ProjectMilestoneMatchMode = "off" | "suggest" | "auto";
|
|
5
|
+
export type ProjectMilestoneMatchBackend = "github" | "linear";
|
|
6
|
+
export type GatePolicyPack = "gittensor" | "oss-anti-slop";
|
|
7
|
+
export type CombineStrategy = "single" | "consensus" | "synthesis";
|
|
8
|
+
export type OnMerge = "either" | "both";
|
|
9
|
+
export type AiReviewLowConfidenceDisposition = "one_shot" | "hold_for_review" | "advisory_only";
|
|
10
|
+
export type ScreenshotTableGateAction = "close" | "advisory";
|
|
11
|
+
export type ScreenshotTableGateConfig = {
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
whenLabels: string[];
|
|
14
|
+
whenPaths: string[];
|
|
15
|
+
action: ScreenshotTableGateAction;
|
|
16
|
+
message?: string | undefined;
|
|
17
|
+
requireViewports: string[];
|
|
18
|
+
requireThemes: string[];
|
|
19
|
+
skillFileUrl?: string | undefined;
|
|
20
|
+
};
|
|
21
|
+
export type CommandAuthorizationRole = "maintainer" | "collaborator" | "pr_author" | "confirmed_miner";
|
|
22
|
+
export type RepositoryCommandAuthorizationPolicy = {
|
|
23
|
+
default: CommandAuthorizationRole[];
|
|
24
|
+
commands: Record<string, CommandAuthorizationRole[]>;
|
|
25
|
+
};
|
|
26
|
+
export type PrTypeLabelSet = Record<string, string>;
|
|
27
|
+
export type LinkedIssueLabelPropagationMapping = {
|
|
28
|
+
issueLabel: string;
|
|
29
|
+
prLabel: string;
|
|
30
|
+
removeOtherTypeLabels: boolean;
|
|
31
|
+
/** Allow this mapping to fire off a linked issue authored by the repo's owner/admin/write-collaborator
|
|
32
|
+
* even when the PR author neither opened nor is assigned to that issue (#priority-linked-issue-gate-
|
|
33
|
+
* ownership). Defaults to `false`/unset (strict author-or-assignee-only behavior) -- a maintainer-reward
|
|
34
|
+
* mapping like `gittensor:priority` should never set this. Mirrors `src/types.ts`'s copy of this type;
|
|
35
|
+
* see `review/linked-issue-label-propagation-fetch.ts`'s `isRepoMaintainerLogin` (app-side only, not
|
|
36
|
+
* duplicated into this engine package since it needs GitHub/fetch/Env access). */
|
|
37
|
+
trustMaintainerAuthoredIssue?: boolean | undefined;
|
|
38
|
+
/** Like `trustMaintainerAuthoredIssue`, but for a mapping that DOES carry real reward weight
|
|
39
|
+
* (#priority-reward-maintainer-trust) -- e.g. `gittensor:priority`. Mirrors `src/types.ts`'s copy of
|
|
40
|
+
* this type; see that copy's doc comment for the full rationale. */
|
|
41
|
+
trustMaintainerAuthoredIssueForReward?: boolean | undefined;
|
|
42
|
+
};
|
|
43
|
+
export type LinkedIssueLabelPropagationMode = "exclusive_type_label";
|
|
44
|
+
export type LinkedIssueLabelPropagationConfig = {
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
mode: LinkedIssueLabelPropagationMode;
|
|
47
|
+
mappings: LinkedIssueLabelPropagationMapping[];
|
|
48
|
+
};
|
|
49
|
+
export type LinkedIssueHardRulesMode = "block" | "off";
|
|
50
|
+
export type LinkedIssueHardRulesConfig = {
|
|
51
|
+
ownerAssignedClose: LinkedIssueHardRulesMode;
|
|
52
|
+
/** Close when an open linked issue is assigned to someone other than the PR author. */
|
|
53
|
+
assignedIssueClose: LinkedIssueHardRulesMode;
|
|
54
|
+
missingPointLabelClose: LinkedIssueHardRulesMode;
|
|
55
|
+
maintainerOnlyLabelClose: LinkedIssueHardRulesMode;
|
|
56
|
+
pointBearingLabels: string[];
|
|
57
|
+
maintainerOnlyLabels: string[];
|
|
58
|
+
defaultLabelRepo: boolean;
|
|
59
|
+
verifyBeforeClose: boolean;
|
|
60
|
+
closeDelaySeconds: number;
|
|
61
|
+
};
|
|
62
|
+
export type UnlinkedIssueGuardrailMode = "hold" | "off";
|
|
63
|
+
export type UnlinkedIssueGuardrailConfig = {
|
|
64
|
+
mode: UnlinkedIssueGuardrailMode;
|
|
65
|
+
minConfidence: number;
|
|
66
|
+
};
|
|
67
|
+
/** Per-capability opt-in to the local-inference AI_ADVISORY binding (#4364): each of these four ADVISORY-ONLY
|
|
68
|
+
* (never gate-blocking) capabilities independently decides whether it routes through env.AI_ADVISORY (when
|
|
69
|
+
* configured) instead of the shared frontier env.AI chain. Config-as-code only -- no DB column, resolved
|
|
70
|
+
* purely from `.gittensory.yml` `settings.advisoryAiRouting` (global default in the shared/root manifest,
|
|
71
|
+
* per-repo override), the same "config-as-code only" shape as unlinkedIssueGuardrail above. Every field
|
|
72
|
+
* defaults to false: an operator must deliberately opt EACH capability in, and even then a repo only
|
|
73
|
+
* actually routes through AI_ADVISORY when the binding itself is configured (env.AI_ADVISORY unset ⇒ every
|
|
74
|
+
* capability stays on env.AI regardless of this config, byte-identical to before this existed). */
|
|
75
|
+
export type AdvisoryAiRoutingConfig = {
|
|
76
|
+
slop: boolean;
|
|
77
|
+
e2eTestGen: boolean;
|
|
78
|
+
planner: boolean;
|
|
79
|
+
summaries: boolean;
|
|
80
|
+
/** Grounded `@gittensory chat <question>` LLM Q&A (#4595). Ollama-first: declines when off or when
|
|
81
|
+
* env.AI_ADVISORY is unconfigured and {@link chatQaFrontierFallback} is not also enabled. Default false. */
|
|
82
|
+
chatQa: boolean;
|
|
83
|
+
/** Opt-in ONLY (#4595 follow-up): when true, chat falls back to the shared frontier env.AI chain if
|
|
84
|
+
* env.AI_ADVISORY is unconfigured, instead of declining. Meaningless unless {@link chatQa} is also true.
|
|
85
|
+
* Default false. */
|
|
86
|
+
chatQaFrontierFallback: boolean;
|
|
87
|
+
/** Closed-set intent-classification router for unrecognized `@gittensory` mentions (#4596). Ollama-only,
|
|
88
|
+
* same as chatQa. Default false. */
|
|
89
|
+
intentRouting: boolean;
|
|
90
|
+
};
|
|
91
|
+
export type ContributorBlacklistEntry = {
|
|
92
|
+
login: string;
|
|
93
|
+
/** Why the account is blocked. Free-text maintainer metadata; not published in automated close comments. */
|
|
94
|
+
reason?: string | undefined;
|
|
95
|
+
/** PR/issue URLs (or other maintainer refs) evidencing the block. */
|
|
96
|
+
evidence?: string[] | undefined;
|
|
97
|
+
/** ISO-8601 date the entry was added. */
|
|
98
|
+
addedAt?: string | undefined;
|
|
99
|
+
};
|
|
100
|
+
export type AutonomyLevel = "observe" | "auto_with_approval" | "auto";
|
|
101
|
+
export type AgentActionClass = "review" | "request_changes" | "approve" | "merge" | "close" | "label" | "review_state_label" | "update_branch" | "assign";
|
|
102
|
+
export type AutonomyPolicy = Partial<Record<AgentActionClass, AutonomyLevel>>;
|
|
103
|
+
export type AutoMergeMethod = "merge" | "squash" | "rebase";
|
|
104
|
+
export type AutoMaintainPolicy = {
|
|
105
|
+
requireApprovals: number;
|
|
106
|
+
mergeMethod: AutoMergeMethod;
|
|
107
|
+
};
|
|
108
|
+
export type RepositorySettings = {
|
|
109
|
+
repoFullName: string;
|
|
110
|
+
commentMode: "off" | "detected_contributors_only" | "all_prs";
|
|
111
|
+
publicAudienceMode: "oss_maintainer" | "gittensor_only";
|
|
112
|
+
publicSignalLevel: "minimal" | "standard";
|
|
113
|
+
checkRunMode: "off" | "enabled";
|
|
114
|
+
checkRunDetailLevel: "minimal" | "standard";
|
|
115
|
+
/** Scheduled re-gate sweep candidate ordering (#3815). `staleness` (default) picks whichever open PR the
|
|
116
|
+
* sweep has gone longest WITHOUT re-gating (see selectRegateCandidates), which is what gives the sweep its
|
|
117
|
+
* documented full-coverage-in-ceil(open/max)-ticks convergence guarantee even under dry-run/pause (when
|
|
118
|
+
* GitHub's own `updatedAt` writes are suppressed). `oldest-first` instead always picks the oldest-created
|
|
119
|
+
* open PRs first, for an operator who wants deterministic creation-order draining over that guarantee.
|
|
120
|
+
* Selection-time only — real-time webhook-driven review is not gated by this and can process any PR at
|
|
121
|
+
* any time regardless of the chosen order. */
|
|
122
|
+
regateSweepOrderMode: "staleness" | "oldest-first";
|
|
123
|
+
/** The actual runtime authority for whether the "LoopOver Orb Review Agent" check-run publishes (#2852).
|
|
124
|
+
* See {@link ReviewCheckMode}. */
|
|
125
|
+
reviewCheckMode: ReviewCheckMode;
|
|
126
|
+
/** Auto-project/milestone matching (#3183). See {@link ProjectMilestoneMatchMode}. Always populated by the DB
|
|
127
|
+
* layer (default `"off"`); optional so existing settings fixtures/callers need not be touched. */
|
|
128
|
+
autoProjectMilestoneMatch?: ProjectMilestoneMatchMode | undefined;
|
|
129
|
+
/** Which backend {@link ProjectMilestoneMatchMode} matches against (#3186). See {@link ProjectMilestoneMatchBackend}.
|
|
130
|
+
* Always populated by the DB layer (default `"github"`); optional so existing settings fixtures/callers need
|
|
131
|
+
* not be touched. */
|
|
132
|
+
autoProjectMilestoneMatchBackend?: ProjectMilestoneMatchBackend | undefined;
|
|
133
|
+
/** Policy pack the gate evaluates under (#692). Default `gittensor` (registry-aware; threads confirmed
|
|
134
|
+
* status for scoring only). `oss-anti-slop` runs the deterministic rules against any author on any repo. */
|
|
135
|
+
gatePack: GatePolicyPack;
|
|
136
|
+
linkedIssueGateMode: GateRuleMode;
|
|
137
|
+
duplicatePrGateMode: GateRuleMode;
|
|
138
|
+
qualityGateMode: GateRuleMode;
|
|
139
|
+
qualityGateMinScore?: number | null | undefined;
|
|
140
|
+
/** Deterministic anti-slop signal (#530/#532). `off` = no slop score; `advisory` = surface the slop
|
|
141
|
+
* score + warnings in context; `block` = ALSO hard-block when slopRisk >= slopGateMinScore (deterministic
|
|
142
|
+
* only, applies to every author like every blocker). Default `off` — opt-in via .gittensory.yml. */
|
|
143
|
+
slopGateMode: GateRuleMode;
|
|
144
|
+
/** PR-size manual-review HOLD (#gate-size). `off` (default/absent) = no size hold; `advisory`/`block` = a PR with
|
|
145
|
+
* >= 10 changed files OR >= 1000 changed (added+deleted) lines that would otherwise pass is HELD for manual review
|
|
146
|
+
* (neutral gate → "manual" verdict), never auto-merged and never a hard failure. Opt-in via `gate.size.mode`. */
|
|
147
|
+
sizeGateMode?: GateRuleMode | undefined;
|
|
148
|
+
/** Lockfile-tamper-risk gate (#2563). `off` (default/absent) = no scan; `advisory`/`block` = a changed
|
|
149
|
+
* `package-lock.json` whose diff changes a `resolved`/`integrity` value WITHOUT the same package's version
|
|
150
|
+
* changing in a changed `package.json`, or whose `resolved` URL points outside `registry.npmjs.org`, produces
|
|
151
|
+
* a `lockfile_tamper_risk` finding (`block` additionally hard-blocks). Distinct from the OSV.dev CVE analyzer
|
|
152
|
+
* in review-enrichment — this is a tamper/integrity-substitution check, not a known-CVE check. Config-as-code
|
|
153
|
+
* only — no DB column or dashboard toggle; set via `.gittensory.yml gate.lockfileIntegrity`. */
|
|
154
|
+
lockfileIntegrityGateMode?: GateRuleMode | undefined;
|
|
155
|
+
/** CLA / license-compatibility gate (#2564). `off` (default/absent) = no CLA check at all; `advisory`/`block` =
|
|
156
|
+
* evaluate the configured detection method(s) (`claConsentPhrase` and/or `claCheckRunName` + `claCheckRunAppSlug`) and raise a
|
|
157
|
+
* `cla_consent_missing` finding when neither confirms consent — `block` also hard-blocks the gate. Config-as-code
|
|
158
|
+
* only (no DB column, mirrors sizeGateMode) — set via `.gittensory.yml gate.claMode`. */
|
|
159
|
+
claGateMode?: GateRuleMode | undefined;
|
|
160
|
+
/** `gate.cla.consentPhrase`: a public-safe-filtered phrase a maintainer requires somewhere in the PR body (e.g.
|
|
161
|
+
* "I have read and agree to the CLA"), matched case-insensitively. `null`/absent ⇒ phrase-match detection is not
|
|
162
|
+
* configured. Config-as-code only, alongside {@link claGateMode}. */
|
|
163
|
+
claConsentPhrase?: string | null | undefined;
|
|
164
|
+
/** `gate.cla.checkRunName`: the name of a separate CLA-bot check-run this repo also runs (e.g. "CLA Assistant
|
|
165
|
+
* Lite"). A `success`/`neutral` conclusion for a check-run with this exact name (case-insensitive), produced
|
|
166
|
+
* by `claCheckRunAppSlug`, also satisfies consent. `null`/absent ⇒ check-run detection is not configured.
|
|
167
|
+
* Config-as-code only, alongside {@link claGateMode}. */
|
|
168
|
+
claCheckRunName?: string | null | undefined;
|
|
169
|
+
/** `gate.cla.checkRunAppSlug`: the trusted GitHub App slug that must have produced `claCheckRunName`. Required
|
|
170
|
+
* for check-run detection so contributor-controlled same-name runs cannot satisfy a blocking CLA gate. */
|
|
171
|
+
claCheckRunAppSlug?: string | null | undefined;
|
|
172
|
+
/** Copycat/plagiarism detection (#1969). `off` (default/absent) = no check; `warn`/`label`/`block` are
|
|
173
|
+
* escalating tiers a future containment/similarity engine would act on. Config-as-code only — no DB column
|
|
174
|
+
* or dashboard toggle; set via `.gittensory.yml gate.copycat.mode`. CURRENTLY INERT: parsed and threaded
|
|
175
|
+
* end-to-end, but no detection engine reads it yet. */
|
|
176
|
+
copycatGateMode?: "off" | "warn" | "label" | "block" | undefined;
|
|
177
|
+
/** `gate.copycat.minScore`: containment/similarity score (0-100) at/above which `copycatGateMode` would act,
|
|
178
|
+
* once the detection engine exists. Config-as-code only, alongside {@link copycatGateMode}. */
|
|
179
|
+
copycatGateMinScore?: number | null | undefined;
|
|
180
|
+
/** `gate.expectedCiContexts` (#selfhost-ci-verification): maintainer-declared CI check/status context names to
|
|
181
|
+
* treat as required when GitHub branch protection returns no readable required-status-checks (unconfigured,
|
|
182
|
+
* or a 403 from a token lacking `administration:read` — common for GitHub App installations). Merged with any
|
|
183
|
+
* branch-protection required contexts when both exist; used ALONE when branch protection is null/empty; a
|
|
184
|
+
* repo with neither configured keeps the existing fold-all fail-closed behavior. A context missing from the
|
|
185
|
+
* commit ⇒ pending; a completed red check for a listed context ⇒ failed; every listed context settled clean
|
|
186
|
+
* ⇒ verified passed (no `ciCompletenessWarning`). Config-as-code only — no DB column; set via
|
|
187
|
+
* `.gittensory.yml gate.expectedCiContexts`. */
|
|
188
|
+
expectedCiContexts?: ReadonlyArray<string> | null | undefined;
|
|
189
|
+
/** Dry-run disposition (#gate-dryrun). When true, the gate renders the would-be merge/close/manual verdict (every
|
|
190
|
+
* advisory sub-gate promoted to block) WITHOUT enforcing — the posted check stays non-blocking. Lets advisory mode
|
|
191
|
+
* preview exactly what it would do before the maintainer flips to real enforcement. Default off. */
|
|
192
|
+
gateDryRun?: boolean | undefined;
|
|
193
|
+
/** Live premerge migrations/** collision recheck (#2550). When true, an agent-driven merge of a PR that
|
|
194
|
+
* touches migrations/** is preceded by a fresh GitHub Trees-API read of the base branch's CURRENT migration
|
|
195
|
+
* filenames — unioned with this PR's own new migration filenames — checked for a live numeric collision.
|
|
196
|
+
* A collision suppresses the merge and holds the PR with a rebase-needed label + comment instead of merging
|
|
197
|
+
* blind. Config-as-code only (no DB column, mirrors gateDryRun) — set via `.gittensory.yml`
|
|
198
|
+
* `gate.premergeContentRecheck`. Default off/undefined — opt-in, since it costs one extra, uncached
|
|
199
|
+
* GitHub API call for any PR that touches migrations/**. */
|
|
200
|
+
premergeContentRecheck?: boolean | undefined;
|
|
201
|
+
/** Merge-readiness gate (#merge-readiness). `off`/`advisory`/`block`. No min-score. Default `off`. */
|
|
202
|
+
mergeReadinessGateMode: GateRuleMode;
|
|
203
|
+
/** Focus-manifest policy gate (#555). When `block`, the focus manifest's declared policy (required-linked
|
|
204
|
+
* issue and test expectations) becomes an enforceable review-agent blocker. Path-based manual-review holds
|
|
205
|
+
* are configured separately through `settings.hardGuardrailGlobs`. An
|
|
206
|
+
* INDEPENDENT dimension, deliberately not folded into the merge-readiness composite. Default `off` — opt-in. */
|
|
207
|
+
manifestPolicyGateMode: GateRuleMode;
|
|
208
|
+
/** Self-authored linked-issue gate. When `block`, the gate closes a PR where the contributor also
|
|
209
|
+
* opened the linked issue (`pr.authorLogin === issue.authorLogin`). Defaults to `advisory` — the finding
|
|
210
|
+
* is surfaced in the review panel but never blocks unless the maintainer opts in. */
|
|
211
|
+
selfAuthoredLinkedIssueGateMode: GateRuleMode;
|
|
212
|
+
/** First-time-contributor grace (#552). RESERVED / currently INERT (#2266): parsed, clamped, and threaded
|
|
213
|
+
* end-to-end, but the gate evaluator never reads it — a genuine newcomer with a real blocker is still
|
|
214
|
+
* one-shot closed exactly like a repeat contributor (blocker findings must remain closure outcomes).
|
|
215
|
+
* Setting this true has no runtime effect today; kept for potential future use. Default false. */
|
|
216
|
+
firstTimeContributorGrace: boolean;
|
|
217
|
+
/** Slop-risk threshold (0-100) at/above which `slopGateMode: block` blocks. Default 60 (the `high` band). */
|
|
218
|
+
slopGateMinScore?: number | null | undefined;
|
|
219
|
+
/** AI-assisted slop advisory (the `slopAiAdvisory` capability). When true AND `slopGateMode != off`, a
|
|
220
|
+
* free/default-reviewer pass (the configured self-host provider, or the legacy Workers-AI pair when
|
|
221
|
+
* none is configured) adds an ADVISORY-only `ai_slop_advisory` finding for semantic slop the
|
|
222
|
+
* deterministic detector cannot quantify. It NEVER feeds slopRisk or the gate (only the deterministic
|
|
223
|
+
* core blocks). Default false — opt-in via `.gittensory.yml gate.slop.aiAdvisory`. */
|
|
224
|
+
slopAiAdvisory: boolean;
|
|
225
|
+
/** AI maintainer review. `off` = no AI; `advisory` = post AI review notes only; `block` = ALSO let a
|
|
226
|
+
* dual-model high-confidence consensus defect become a gate blocker (confirmed-contributors only,
|
|
227
|
+
* like every other blocker). Default `off` — AI is opt-in. */
|
|
228
|
+
aiReviewMode: GateRuleMode;
|
|
229
|
+
/** Bring-your-own-key: when true and a provider key is configured for the repo, the advisory AI review
|
|
230
|
+
* is generated by the maintainer's frontier model (Anthropic/OpenAI) instead of the free/default
|
|
231
|
+
* reviewer. The consensus blocker always uses the free/default reviewer pair regardless (the configured
|
|
232
|
+
* self-host provider, or the legacy Workers-AI pair when none is configured), so BYOK never changes who
|
|
233
|
+
* can be blocked. Default false. */
|
|
234
|
+
aiReviewByok: boolean;
|
|
235
|
+
/** Config-as-code BYOK provider for the advisory write-up. `null` = use the configured key's own
|
|
236
|
+
* provider. When set, it must match the stored key's provider or BYOK is skipped (falls back to the
|
|
237
|
+
* free/default reviewer). The secret key itself is never here — only via the encrypted key store. */
|
|
238
|
+
aiReviewProvider?: "anthropic" | "openai" | null | undefined;
|
|
239
|
+
/** Config-as-code model override for the BYOK advisory write-up (e.g. "claude-3-5-sonnet-latest").
|
|
240
|
+
* `null` = use the key record's model, else a conservative per-provider default. */
|
|
241
|
+
aiReviewModel?: string | null | undefined;
|
|
242
|
+
/** Review EVERY PR's author, not only confirmed Gittensor contributors. The AI maintainer review is
|
|
243
|
+
* confirmed-contributor-gated by default (an AI-spend guard). When true the review runs for any author —
|
|
244
|
+
* intended for a self-host operator who wants real reviews on all PRs (incl. their own) and pays for the
|
|
245
|
+
* AI themselves. Default false — opt-in via `.gittensory.yml gate.aiReview.allAuthors`. Independent of
|
|
246
|
+
* `aiReviewMode`: `off` still means no AI; this only widens WHO an enabled review covers. */
|
|
247
|
+
aiReviewAllAuthors: boolean;
|
|
248
|
+
/** Configured AI-reviewer confidence floor (0-1) for close calibration (#7). Under `aiReviewMode: block`, AI
|
|
249
|
+
* defect findings remain blockers even when their confidence is below this floor; the floor is retained as
|
|
250
|
+
* configurable context, not a manual-review downgrade. Config-as-code only — set via `.gittensory.yml
|
|
251
|
+
* gate.aiReview.closeConfidence` (no dashboard/DB column); unset ⇒ the gate uses the 0.93 default. Clamped to
|
|
252
|
+
* [0,1] at parse time. */
|
|
253
|
+
aiReviewCloseConfidence?: number | null | undefined;
|
|
254
|
+
/** Per-repo dual-AI combine-strategy override (#2567). Config-as-code only — set via `.gittensory.yml
|
|
255
|
+
* gate.aiReview.combine` (no dashboard/DB column); unset ⇒ the self-host operator's `AI_REVIEW_PLAN.combine`
|
|
256
|
+
* boot config (or `consensus` if the operator set nothing). A REFINEMENT of the operator's plan, not a
|
|
257
|
+
* bypass — `runGittensoryAiReview` clamps the resolved `onMerge` to the operator's floor (see
|
|
258
|
+
* {@link aiReviewOnMerge}); `combine` itself carries no floor semantics (single/consensus/synthesis are not
|
|
259
|
+
* ordered by strictness). */
|
|
260
|
+
aiReviewCombine?: CombineStrategy | null | undefined;
|
|
261
|
+
/** Per-repo `synthesis` merge-rule override (#2567): `either` blocks on ANY one reviewer's blocker (the
|
|
262
|
+
* STRICTER rule); `both` blocks only when every reviewer agrees (the more PERMISSIVE rule). Config-as-code
|
|
263
|
+
* only — set via `.gittensory.yml gate.aiReview.onMerge` (no dashboard/DB column). A repo override can only
|
|
264
|
+
* TIGHTEN the operator's `AI_REVIEW_PLAN.onMerge` floor (e.g. `either` → `either` is a no-op; `both` → an
|
|
265
|
+
* attempted loosening is clamped back to `either`). When the operator has not set an `onMerge` floor, any
|
|
266
|
+
* per-repo value is honored unclamped. See `resolveEffectiveAiReviewOnMerge` in `services/ai-review.ts`. */
|
|
267
|
+
aiReviewOnMerge?: OnMerge | null | undefined;
|
|
268
|
+
/** Per-repo reviewer-pair override (#2567): named self-host providers (e.g. `{ model: "claude-code" }`,
|
|
269
|
+
* `{ model: "codex" }`) to run instead of the operator's `AI_REVIEW_PLAN.reviewers` (or the free Workers-AI
|
|
270
|
+
* pair when the operator configured none). Config-as-code only — set via `.gittensory.yml
|
|
271
|
+
* gate.aiReview.reviewers` (no dashboard/DB column). Unlike {@link aiReviewOnMerge}, WHICH reviewers run
|
|
272
|
+
* carries no operator floor to violate (the floor is what triggers a hold/block, not who evaluates it), so a
|
|
273
|
+
* repo override always wins unclamped when set. */
|
|
274
|
+
aiReviewReviewers?: ReadonlyArray<{
|
|
275
|
+
model: string;
|
|
276
|
+
fallback?: string | null | undefined;
|
|
277
|
+
}> | null | undefined;
|
|
278
|
+
/** When TRUE, the repo OWNER's (and maintainer's) own PRs are eligible for auto-CLOSE like a contributor's
|
|
279
|
+
* (still subject to the `close` autonomy class + the same adverse-signal conditions). Default FALSE — owner
|
|
280
|
+
* PRs are exempt from auto-close (merge or manual-hold only). Per-repo configurable so maintainers choose
|
|
281
|
+
* rather than inheriting a hardwired opinion. */
|
|
282
|
+
closeOwnerAuthors: boolean;
|
|
283
|
+
autoLabelEnabled: boolean;
|
|
284
|
+
gittensorLabel: string;
|
|
285
|
+
createMissingLabel: boolean;
|
|
286
|
+
/** #label-decoupling: independently gates the per-PR TYPE/taxonomy label (bug/feature by the PR
|
|
287
|
+
* title, or priority via linked-issue label propagation — see `resolvePrTypeLabel` in
|
|
288
|
+
* `settings/pr-type-label.ts`). Distinct from {@link autoLabelEnabled} (which governs only the
|
|
289
|
+
* base {@link gittensorLabel} context label) and from `decidePublicSurface`'s public-surface gate
|
|
290
|
+
* (miner detection / `publicAudienceMode` / `includeMaintainerAuthors` / bot-author exclusion) —
|
|
291
|
+
* type labels are internal triage metadata applied unconditionally to every PR, not a
|
|
292
|
+
* contributor-facing signal, so neither of those public-surface conditions should suppress them.
|
|
293
|
+
* Default TRUE (matches the prior de-facto behavior before this field existed, when type labels
|
|
294
|
+
* were gated by `autoLabelEnabled` nested inside the public-surface check). Always populated by
|
|
295
|
+
* the DB layer; optional so existing settings fixtures/callers need not be touched. */
|
|
296
|
+
typeLabelsEnabled?: boolean | undefined;
|
|
297
|
+
/** Per-repo override of the TYPE/taxonomy label NAMES, keyed by category (#priority-linked-issue-gate,
|
|
298
|
+
* #label-modularity). Defaults to `DEFAULT_TYPE_LABELS` (`gittensor:bug`/`gittensor:feature`/
|
|
299
|
+
* `gittensor:priority`) in `settings/pr-type-label.ts` — a repo can override just one name (e.g. only
|
|
300
|
+
* `priority`) and keep the others default, AND/OR add arbitrary additional categories beyond the
|
|
301
|
+
* built-in three (e.g. `security: "area:security"`) for its own taxonomy. Always populated by the DB
|
|
302
|
+
* layer; optional so existing settings fixtures/callers need not be touched. */
|
|
303
|
+
typeLabels?: PrTypeLabelSet | undefined;
|
|
304
|
+
/** Linked-issue label propagation (#priority-linked-issue-gate): the ONLY mechanism that can ever
|
|
305
|
+
* select the configured priority label (or any other configured mapping's PR label) — never
|
|
306
|
+
* inferred from a PR's title, changed files, AI output, or existing PR labels. Default disabled
|
|
307
|
+
* (`enabled: false`, no mappings) — a self-hoster opts in per repo. Always populated by the DB
|
|
308
|
+
* layer; optional so existing settings fixtures/callers need not be touched. */
|
|
309
|
+
linkedIssueLabelPropagation?: LinkedIssueLabelPropagationConfig | undefined;
|
|
310
|
+
/** Deterministic linked-issue hard rules. Config-as-code only; set with
|
|
311
|
+
* `.gittensory.yml settings.linkedIssueHardRules` in private/global or per-repo config. These rules close
|
|
312
|
+
* contributor PRs that link ineligible issues before spending AI review budget: owner/other-assigned,
|
|
313
|
+
* maintainer-only, or missing point-label issues. Defaults all-off so self-hosters opt into their own policy. */
|
|
314
|
+
linkedIssueHardRules?: LinkedIssueHardRulesConfig | undefined;
|
|
315
|
+
/** Same-account issue-avoidance guardrail (#unlinked-issue-guardrail). Config-as-code only; set with
|
|
316
|
+
* `.gittensory.yml settings.unlinkedIssueGuardrail` in private/global or per-repo config. Defaults
|
|
317
|
+
* all-off so a self-hoster opts into their own credibility-gate-farming defense. */
|
|
318
|
+
unlinkedIssueGuardrail?: UnlinkedIssueGuardrailConfig | undefined;
|
|
319
|
+
/** Per-capability local-inference routing (#4364). Config-as-code only; set with `.gittensory.yml
|
|
320
|
+
* settings.advisoryAiRouting` in shared/global or per-repo config (global default + per-repo override,
|
|
321
|
+
* the same deep-merge precedence every other settings field uses). Defaults all-false so every advisory
|
|
322
|
+
* capability stays on the shared frontier env.AI chain until an operator opts each one in. */
|
|
323
|
+
advisoryAiRouting?: AdvisoryAiRoutingConfig | undefined;
|
|
324
|
+
publicSurface: "off" | "comment_and_label" | "comment_only" | "label_only";
|
|
325
|
+
includeMaintainerAuthors: boolean;
|
|
326
|
+
requireLinkedIssue: boolean;
|
|
327
|
+
backfillEnabled: boolean;
|
|
328
|
+
/** Opt-in for the public, unauthenticated README status badge (#541). Always populated by the DB layer
|
|
329
|
+
* (default false); optional so existing settings fixtures/callers need not be touched. */
|
|
330
|
+
badgeEnabled?: boolean | undefined;
|
|
331
|
+
/** Opt-in for the public per-repo review-quality page (#2568). Always populated by the DB layer
|
|
332
|
+
* (default false); optional so existing settings fixtures/callers need not be touched. */
|
|
333
|
+
publicQualityMetrics?: boolean | undefined;
|
|
334
|
+
commandAuthorization?: RepositoryCommandAuthorizationPolicy | undefined;
|
|
335
|
+
/** Per-repo contributor blacklist (#1425, anti-abuse): banned GitHub logins whose PRs/issues the engine
|
|
336
|
+
* deterministically closes ahead of merit review. Layered the same as other settings (`.gittensory.yml` >
|
|
337
|
+
* DB) and unioned with the shared/global list at the point of use. Always populated by the DB layer
|
|
338
|
+
* (default `[]`); optional so existing settings fixtures/callers need not be touched. */
|
|
339
|
+
contributorBlacklist?: ContributorBlacklistEntry[] | undefined;
|
|
340
|
+
/** The label applied to a blacklisted contributor's PR (#1425). Configurable per-repo (dashboard/DB +
|
|
341
|
+
* `.gittensory.yml` `settings.blacklistLabel`); defaults to `"slop"` so the disposition works regardless of
|
|
342
|
+
* the label a repo sets. Explicit `null` closes WITHOUT applying any label (the same load-bearing-null idiom
|
|
343
|
+
* as {@link contributorOpenPrCap}) -- distinct from omitted/undefined, which uses the default. Always
|
|
344
|
+
* populated by the DB layer (default `"slop"`); optional so existing settings fixtures/callers need not be
|
|
345
|
+
* touched (mirrors the sibling `contributorBlacklist`). */
|
|
346
|
+
blacklistLabel?: string | null | undefined;
|
|
347
|
+
/** Per-contributor open-PR cap (#2270, anti-abuse): the max PRs a single non-owner/admin/bot contributor may
|
|
348
|
+
* have open on this repo at once. `null`/absent (default) = no cap, byte-identical to today. Layered like
|
|
349
|
+
* every other settings field (`.gittensory.yml` `settings.contributorOpenPrCap` > DB > `null`). Enforcement
|
|
350
|
+
* (closing the newest PR(s) over the cap) is a separate follow-up; this field only carries the threshold. */
|
|
351
|
+
contributorOpenPrCap?: number | null | undefined;
|
|
352
|
+
/** Per-contributor open-issue cap (#2270, anti-abuse): same shape and precedence as {@link contributorOpenPrCap},
|
|
353
|
+
* applied to open issues instead of open PRs. `null`/absent (default) = no cap. */
|
|
354
|
+
contributorOpenIssueCap?: number | null | undefined;
|
|
355
|
+
/** The label applied to a PR/issue closed for exceeding a per-contributor open-item cap (#2270). Same
|
|
356
|
+
* configurable-with-fallback shape as {@link blacklistLabel} (including the explicit-`null`-closes-without-a-
|
|
357
|
+
* label idiom); defaults to `"over-contributor-limit"` so the disposition works regardless of the label a
|
|
358
|
+
* repo sets. Always populated by the DB layer; optional so existing settings fixtures/callers need not be
|
|
359
|
+
* touched. */
|
|
360
|
+
contributorCapLabel?: string | null | undefined;
|
|
361
|
+
/** Cancel in-flight CI runs on a contributor_cap close (#2462, anti-abuse): when true, after a PR is
|
|
362
|
+
* auto-closed for exceeding {@link contributorOpenPrCap}, gittensory lists and cancels that PR's
|
|
363
|
+
* in-progress/queued Actions runs at its head SHA. Requires the App installation to have granted
|
|
364
|
+
* `actions: write` -- degrades gracefully (skipped + logged, never blocks the close) when it hasn't.
|
|
365
|
+
* `null`/undefined (the DB-layer default) means "unset" and falls back to the
|
|
366
|
+
* `CONTRIBUTOR_CAP_CANCEL_CI_DEFAULT` env var -- unlike most boolean toggles, this one is nullable so an
|
|
367
|
+
* explicit `false` (opt back out) is distinguishable from "not configured" for that fallback. */
|
|
368
|
+
contributorCapCancelCi?: boolean | null | undefined;
|
|
369
|
+
/** Review-request nagging cooldown (#2463, anti-abuse): throttle a contributor repeatedly pinging
|
|
370
|
+
* `@gittensory` (any command) on this repo. `"off"` (default) is a no-op; `"hold"` posts a deterministic
|
|
371
|
+
* cooldown reply and takes no further action; `"close"` additionally closes the thread (PR threads only in
|
|
372
|
+
* v1 — a plain issue thread degrades to `"hold"` behavior until #2493's `closeIssue` primitive lands).
|
|
373
|
+
* Always populated by the DB layer (default `"off"`); optional so existing settings fixtures/callers need
|
|
374
|
+
* not be touched. */
|
|
375
|
+
reviewNagPolicy?: "off" | "hold" | "close" | undefined;
|
|
376
|
+
/** Review-nag cooldown (#2463): how many `@gittensory` pings a contributor may make on this repo within
|
|
377
|
+
* {@link reviewNagCooldownDays} before the (N+1)th is throttled. Always populated by the DB layer (default
|
|
378
|
+
* `3`); optional so existing settings fixtures/callers need not be touched. Only meaningful when
|
|
379
|
+
* {@link reviewNagPolicy} is not `"off"`. */
|
|
380
|
+
reviewNagMaxPings?: number | undefined;
|
|
381
|
+
/** Review-nag cooldown (#2463): the rolling window (in days) {@link reviewNagMaxPings} counts against. Always
|
|
382
|
+
* populated by the DB layer (default `5`); optional so existing settings fixtures/callers need not be
|
|
383
|
+
* touched. */
|
|
384
|
+
reviewNagCooldownDays?: number | undefined;
|
|
385
|
+
/** The label applied to a thread closed for review-nag cooldown (#2463), mirroring {@link blacklistLabel}'s
|
|
386
|
+
* configurable-with-fallback shape (including the explicit-`null`-closes-without-a-label idiom). Always
|
|
387
|
+
* populated by the DB layer (default `"review-nag-cooldown"`); optional so existing settings
|
|
388
|
+
* fixtures/callers need not be touched. */
|
|
389
|
+
reviewNagLabel?: string | null | undefined;
|
|
390
|
+
/** Maintainer-mention nag moderation: GitHub logins to ALSO throttle under the review-nag cooldown when the
|
|
391
|
+
* thread author repeatedly @-mentions them (on top of the bot's own `@gittensory` handle) -- e.g. a
|
|
392
|
+
* maintainer login instead of the bot, for a contributor who keeps tagging a specific person for review.
|
|
393
|
+
* Counted independently per mentioned login and independently of the `@gittensory` counter, but reuses the
|
|
394
|
+
* SAME {@link reviewNagPolicy}/{@link reviewNagMaxPings}/{@link reviewNagCooldownDays}/{@link reviewNagLabel}
|
|
395
|
+
* thresholds/action/label -- one cooldown policy, multiple watched mention targets. `[]`/undefined (default)
|
|
396
|
+
* = no logins watched, zero behavior change. Never fires for the repo owner, admin logins, automation bots,
|
|
397
|
+
* or a login on {@link autoCloseExemptLogins}. */
|
|
398
|
+
reviewNagMonitoredMentions?: string[] | undefined;
|
|
399
|
+
/** Shared repo-scoped exemption list (#2463, anti-abuse): GitHub logins that are NEVER throttled or closed by
|
|
400
|
+
* gittensory's deterministic anti-abuse mechanisms (review-nag and the per-contributor open-item cap above),
|
|
401
|
+
* on top of the standing owner/admin/automation-bot exemption. Always populated by the DB layer (default
|
|
402
|
+
* `[]`); optional so existing settings fixtures/callers need not be touched. */
|
|
403
|
+
autoCloseExemptLogins?: string[] | undefined;
|
|
404
|
+
/** Hard manual-review guardrail globs. Config-as-code only: set in private/global or per-repo
|
|
405
|
+
* `.gittensory.yml` under `settings.hardGuardrailGlobs`. Absent means no path guardrails. Arrays are
|
|
406
|
+
* replacement overlays, so a repo can clear a global default with `[]`. */
|
|
407
|
+
hardGuardrailGlobs?: string[] | null | undefined;
|
|
408
|
+
/** Label applied when an otherwise-ready PR is held for manual review by a guardrail. Config-as-code only;
|
|
409
|
+
* `null` disables the label while keeping the hold. Distinct from `review_state_label`, so operators can
|
|
410
|
+
* apply one manual-review label without enabling ready/changes-requested disposition labels. */
|
|
411
|
+
manualReviewLabel?: string | null | undefined;
|
|
412
|
+
/** Optional review-state label names. Config-as-code only; each `null` disables that specific label. These are
|
|
413
|
+
* deliberately generic defaults rather than `gittensory:*` names so self-hosters can opt into their own
|
|
414
|
+
* taxonomy without inheriting project-specific labels. */
|
|
415
|
+
readyToMergeLabel?: string | null | undefined;
|
|
416
|
+
changesRequestedLabel?: string | null | undefined;
|
|
417
|
+
migrationCollisionLabel?: string | null | undefined;
|
|
418
|
+
pendingClosureLabel?: string | null | undefined;
|
|
419
|
+
/** Force-rebase-before-merge window in minutes (#2552, anti-race). When a base branch has advanced within
|
|
420
|
+
* this many minutes of the actual merge-decision moment, an agent-driven merge forces an `update_branch` +
|
|
421
|
+
* fresh CI recheck cycle first, rather than trusting a `mergeableState: clean` read that may already be
|
|
422
|
+
* stale relative to a sibling commit that just landed on the base. `null`/undefined (default) = never
|
|
423
|
+
* force -- a `mergeable_state: clean` read is trusted exactly as it is today. Layered like every other
|
|
424
|
+
* settings field (`.gittensory.yml` `gate.requireFreshRebaseWindow` > DB > `null`). */
|
|
425
|
+
requireFreshRebaseWindowMinutes?: number | null | undefined;
|
|
426
|
+
/** Account-age throttle (#2561, anti-abuse): an account younger than this many days gets the
|
|
427
|
+
* {@link newAccountLabel} and a tighter effective contributor cap — friction/visibility, NEVER an
|
|
428
|
+
* automatic close on account age alone. `null`/undefined (default) = off. Never fires for the repo
|
|
429
|
+
* owner, admin logins, or automation bots. Applies on both PR and issue contributor-cap paths. */
|
|
430
|
+
accountAgeThresholdDays?: number | null | undefined;
|
|
431
|
+
/** The label applied to a below-threshold-age account's PR (#2561), mirroring {@link blacklistLabel}'s
|
|
432
|
+
* configurable-with-fallback shape. Always populated by the DB layer (default `"new-account"`); optional so
|
|
433
|
+
* existing settings fixtures/callers need not be touched. */
|
|
434
|
+
newAccountLabel?: string | undefined;
|
|
435
|
+
/** Per-command @gittensory rate limit (#2560, anti-abuse): generalizes the review-nag cooldown's counting
|
|
436
|
+
* pattern (the audit-events ledger) to EVERY `@gittensory` command, keyed by `(actor, command, targetKey)` --
|
|
437
|
+
* independent of, and complementary to, review-nag's own narrower thread-author-only scope. `"off"` (default)
|
|
438
|
+
* is a no-op; `"hold"` posts a deterministic cooldown reply and skips the command's own dispatch. Always
|
|
439
|
+
* populated by the DB layer (default `"off"`); optional so existing settings fixtures/callers need not be
|
|
440
|
+
* touched. */
|
|
441
|
+
commandRateLimitPolicy?: "off" | "hold" | undefined;
|
|
442
|
+
/** Per-command rate limit (#2560): how many invocations of a single command an actor may make within
|
|
443
|
+
* {@link commandRateLimitWindowHours} before the (N+1)th is throttled -- for a CHEAP command (cache-only,
|
|
444
|
+
* no AI orchestrator call). Always populated by the DB layer (default `20`); optional so existing settings
|
|
445
|
+
* fixtures/callers need not be touched. Only meaningful when {@link commandRateLimitPolicy} is not `"off"`. */
|
|
446
|
+
commandRateLimitMaxPerWindow?: number | undefined;
|
|
447
|
+
/** Per-command rate limit (#2560): the same threshold as {@link commandRateLimitMaxPerWindow}, but for an
|
|
448
|
+
* AI-cost-bearing command (dispatches to a real orchestrator call: `ask`, `blockers`, `preflight`,
|
|
449
|
+
* `reviewability`, `packet`, `duplicate-check`, `next-action`, `repo-fit`). Deliberately tighter than the
|
|
450
|
+
* cheap-command default. Always populated by the DB layer (default `5`); optional so existing settings
|
|
451
|
+
* fixtures/callers need not be touched. */
|
|
452
|
+
commandRateLimitAiMaxPerWindow?: number | undefined;
|
|
453
|
+
/** Per-command rate limit (#2560): the rolling window (in hours) both {@link commandRateLimitMaxPerWindow}
|
|
454
|
+
* and {@link commandRateLimitAiMaxPerWindow} count against. Always populated by the DB layer (default `24`);
|
|
455
|
+
* optional so existing settings fixtures/callers need not be touched. */
|
|
456
|
+
commandRateLimitWindowHours?: number | undefined;
|
|
457
|
+
/** Agent-layer autonomy dial (#773): per-action-class level. Always populated by the DB layer (default
|
|
458
|
+
* `{}` = deny-by-default = "observe" for every class); optional so existing settings fixtures/callers
|
|
459
|
+
* need not be touched. The single source the action layer (#778) reads via `resolveAutonomy`. */
|
|
460
|
+
autonomy?: AutonomyPolicy | undefined;
|
|
461
|
+
/** Auto-maintain policy (#774): merge method + approval count. Always populated by the DB layer with
|
|
462
|
+
* defaults (squash / 1 approval); optional so existing settings fixtures/callers need not be touched. */
|
|
463
|
+
autoMaintain?: AutoMaintainPolicy | undefined;
|
|
464
|
+
/** Per-repo agent kill-switch (#776): when true, the action layer takes NO action on this repo (the
|
|
465
|
+
* global env switch overrides this too). Default false. */
|
|
466
|
+
agentPaused?: boolean | undefined;
|
|
467
|
+
/** Per-repo dry-run/shadow mode (#776): when true, the action layer records what it WOULD do without
|
|
468
|
+
* performing any GitHub mutation. Default false. */
|
|
469
|
+
agentDryRun?: boolean | undefined;
|
|
470
|
+
/** Per-repo override of the global DB-backed agent freeze (#4372): when true, this repo's actions execute
|
|
471
|
+
* even while `global_agent_controls.frozen` is set, so an operator can re-activate one repo at a time
|
|
472
|
+
* without lifting the fleet-wide brake. Never overrides the `AGENT_ACTIONS_PAUSED` env var, and
|
|
473
|
+
* {@link agentPaused} on this same repo still wins over it. Default false. */
|
|
474
|
+
agentGlobalFreezeOverride?: boolean | undefined;
|
|
475
|
+
/** Moderation-rules engine (#selfhost-mod-engine): whether the whole layer runs on THIS repo. `"inherit"`
|
|
476
|
+
* (the DB default) defers to `global_moderation_config.enabled`; `"off"`/`"enabled"` force this repo
|
|
477
|
+
* regardless of the global default. Always populated by the DB layer; optional so existing settings
|
|
478
|
+
* fixtures/callers need not be touched. */
|
|
479
|
+
moderationGateMode?: "inherit" | "off" | "enabled" | undefined;
|
|
480
|
+
/** Moderation-rules engine: a per-repo override of WHICH of the anti-abuse mechanisms (contributor cap,
|
|
481
|
+
* blacklist, review-nag, review-evasion) feed a contributor's shared, cross-repo violation tally.
|
|
482
|
+
* `undefined`/absent ⇒ inherit the global rule set (`resolveEffectiveModerationRules`'s default shape). */
|
|
483
|
+
moderationRules?: ("contributor_cap" | "blacklist" | "review_nag" | "review_evasion")[] | undefined;
|
|
484
|
+
/** Moderation-rules engine: per-repo override of the label applied at >=1 lifetime violation. `undefined` ⇒
|
|
485
|
+
* the global config's `warningLabel` (itself defaulting to `"mod:warning"`). */
|
|
486
|
+
moderationWarningLabel?: string | undefined;
|
|
487
|
+
/** Moderation-rules engine: per-repo override of the label applied at >= the ban threshold. `undefined` ⇒
|
|
488
|
+
* the global config's `bannedLabel` (itself defaulting to `"mod:banned"`). */
|
|
489
|
+
moderationBannedLabel?: string | undefined;
|
|
490
|
+
/** Review-evasion protection (#review-evasion-protection): a contributor closing or converting their OWN
|
|
491
|
+
* PR to draft while gittensory has an ACTIVE review pass running against it is dodging the one-shot
|
|
492
|
+
* review process. `"off"` (the default) disables detection entirely; `"close"` reopens (if needed) and
|
|
493
|
+
* re-closes as the App -- a close the contributor cannot themselves reopen (#one-shot-reopen) -- applies
|
|
494
|
+
* the configured label/comment, and records a `review_evasion` moderation strike. */
|
|
495
|
+
reviewEvasionProtection?: "off" | "close" | undefined;
|
|
496
|
+
/** Review-evasion protection: label applied alongside the enforcement close, gated on `close` autonomy
|
|
497
|
+
* like every other anti-abuse label (#label-scoping), mirroring {@link blacklistLabel}'s shape. `undefined`
|
|
498
|
+
* ⇒ the `"review-evasion"` default; explicit `null` ⇒ close without any label. */
|
|
499
|
+
reviewEvasionLabel?: string | null | undefined;
|
|
500
|
+
/** Review-evasion protection: whether to post the public explanation comment before the enforcement close.
|
|
501
|
+
* Default true. */
|
|
502
|
+
reviewEvasionComment?: boolean | undefined;
|
|
503
|
+
/** Merge-train FIFO gate (#selfhost-merge-train): `"off"` keeps current behavior, `"audit"` logs would-hold
|
|
504
|
+
* decisions, and `"enforce"` defers a merge behind a still-viable older sibling. */
|
|
505
|
+
mergeTrainMode?: "off" | "audit" | "enforce" | undefined;
|
|
506
|
+
/** Config-driven before/after screenshot-table gate (#2006): a DETERMINISTIC check (no AI, zero hallucination
|
|
507
|
+
* risk) that a contributor visual/frontend PR's body contains a markdown table with before/after image
|
|
508
|
+
* markup, scoped to the repo's configured labels/paths (`whenLabels`/`whenPaths`, OR-matched). Off by
|
|
509
|
+
* default (`enabled: false`) -- opt in per repo, mirroring every other anti-abuse mechanism's shape. See
|
|
510
|
+
* `review/screenshot-table-gate.ts` for the normalizer and the pure evaluator. */
|
|
511
|
+
screenshotTableGate?: ScreenshotTableGateConfig | undefined;
|
|
512
|
+
createdAt?: string | null | undefined;
|
|
513
|
+
updatedAt?: string | null | undefined;
|
|
514
|
+
};
|