@deftai/directive-core 0.93.0 → 0.95.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/dist/authz/classify.js +485 -0
- package/dist/cache/fetch.d.ts +29 -0
- package/dist/cache/fetch.js +131 -4
- package/dist/cache/operations.d.ts +8 -0
- package/dist/cache/operations.js +67 -4
- package/dist/check/cached-orchestrator.js +11 -0
- package/dist/check/consumer-gate-integrity.d.ts +68 -0
- package/dist/check/consumer-gate-integrity.js +265 -0
- package/dist/check/index.d.ts +1 -0
- package/dist/check/index.js +1 -0
- package/dist/check/orchestrator.js +10 -0
- package/dist/content-contracts/skills/greptile-detector.d.ts +9 -0
- package/dist/content-contracts/skills/greptile-detector.js +9 -2
- package/dist/doctor/main.js +98 -9
- package/dist/doctor/types.d.ts +2 -2
- package/dist/finish-loop/pr-finish-loop.js +1 -0
- package/dist/freshness/bind.d.ts +67 -0
- package/dist/freshness/bind.js +201 -0
- package/dist/freshness/cli.d.ts +30 -0
- package/dist/freshness/cli.js +180 -0
- package/dist/freshness/compare.d.ts +14 -0
- package/dist/freshness/compare.js +134 -0
- package/dist/freshness/generation.d.ts +44 -0
- package/dist/freshness/generation.js +172 -0
- package/dist/freshness/index.d.ts +13 -0
- package/dist/freshness/index.js +13 -0
- package/dist/freshness/report.d.ts +43 -0
- package/dist/freshness/report.js +139 -0
- package/dist/freshness/types.d.ts +70 -0
- package/dist/freshness/types.js +30 -0
- package/dist/handoff-evidence/index.d.ts +8 -0
- package/dist/handoff-evidence/index.js +7 -0
- package/dist/handoff-evidence/validate.d.ts +105 -0
- package/dist/handoff-evidence/validate.js +423 -0
- package/dist/hooks/dispatcher.d.ts +27 -2
- package/dist/hooks/dispatcher.js +134 -14
- package/dist/hooks/readonly.d.ts +14 -0
- package/dist/hooks/readonly.js +126 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/init-deposit/agent-hooks.d.ts +1 -1
- package/dist/init-deposit/agent-hooks.js +5 -2
- package/dist/init-deposit/init-deposit.d.ts +7 -1
- package/dist/init-deposit/init-deposit.js +24 -4
- package/dist/init-deposit/refresh.d.ts +9 -1
- package/dist/init-deposit/refresh.js +48 -5
- package/dist/intake/issue-ingest.d.ts +20 -0
- package/dist/intake/issue-ingest.js +58 -0
- package/dist/policy/index.d.ts +4 -0
- package/dist/policy/index.js +50 -1
- package/dist/policy/min-greptile-confidence.d.ts +57 -0
- package/dist/policy/min-greptile-confidence.js +123 -0
- package/dist/pr-merge-readiness/compute.d.ts +11 -1
- package/dist/pr-merge-readiness/compute.js +17 -4
- package/dist/pr-merge-readiness/evaluate.d.ts +8 -1
- package/dist/pr-merge-readiness/evaluate.js +7 -4
- package/dist/pr-merge-readiness/mergeability.d.ts +7 -1
- package/dist/pr-merge-readiness/mergeability.js +14 -2
- package/dist/pr-monitor/main.d.ts +2 -0
- package/dist/pr-monitor/main.js +31 -1
- package/dist/pr-monitor/monitor.js +5 -1
- package/dist/pr-monitor/readiness.js +3 -1
- package/dist/pr-monitor/types.d.ts +8 -0
- package/dist/pr-wait-mergeable/cascade.d.ts +8 -0
- package/dist/pr-wait-mergeable/cascade.js +28 -1
- package/dist/pr-wait-mergeable/main.d.ts +2 -0
- package/dist/pr-wait-mergeable/main.js +16 -0
- package/dist/pr-wait-mergeable/types.d.ts +3 -1
- package/dist/pr-wait-mergeable/wrappers.d.ts +6 -0
- package/dist/pr-wait-mergeable/wrappers.js +3 -0
- package/dist/pr-watch/constants.d.ts +4 -1
- package/dist/pr-watch/constants.js +5 -2
- package/dist/pr-watch/main.js +1 -0
- package/dist/pr-watch/probe.d.ts +1 -1
- package/dist/pr-watch/probe.js +4 -1
- package/dist/pr-watch/types.d.ts +7 -1
- package/dist/pr-watch/watch.js +3 -2
- package/dist/release-e2e/greenfield-python-free-smoke.js +7 -3
- package/dist/review-monitor/index.d.ts +1 -0
- package/dist/review-monitor/index.js +1 -0
- package/dist/review-monitor/l4-owner.d.ts +46 -0
- package/dist/review-monitor/l4-owner.js +262 -0
- package/dist/session/ritual-entrypoint.d.ts +6 -2
- package/dist/session/ritual-entrypoint.js +15 -2
- package/dist/session/session-ready.js +31 -14
- package/dist/session/session-start.d.ts +2 -1
- package/dist/session/session-start.js +66 -3
- package/dist/session/verify-session-ritual.d.ts +4 -2
- package/dist/session/verify-session-ritual.js +11 -11
- package/dist/slash/product-set.js +4 -1
- package/dist/swarm/verify-review-clean.d.ts +4 -3
- package/dist/swarm/verify-review-clean.js +28 -73
- package/dist/tool-events/classify.js +1 -0
- package/dist/triage/classify/index.d.ts +9 -0
- package/dist/triage/classify/index.js +34 -2
- package/dist/triage/classify/label-mirror.d.ts +143 -0
- package/dist/triage/classify/label-mirror.js +684 -0
- package/dist/triage/help/registry-data.d.ts +7 -7
- package/dist/triage/help/registry-data.js +27 -7
- package/dist/triage/queue/show.d.ts +1 -1
- package/dist/triage/queue/show.js +4 -2
- package/dist/triage/welcome/writers.js +16 -7
- package/dist/umbrella-current-shape/index.d.ts +45 -0
- package/dist/umbrella-current-shape/index.js +162 -8
- package/dist/vbrief-reconcile/index.d.ts +2 -2
- package/dist/vbrief-reconcile/index.js +1 -1
- package/dist/vbrief-reconcile/types.d.ts +14 -0
- package/dist/vbrief-reconcile/umbrellas.d.ts +31 -2
- package/dist/vbrief-reconcile/umbrellas.js +231 -19
- package/dist/vbrief-validate/project-definition.js +1 -1
- package/dist/verify-env/agent-hook-readiness.d.ts +42 -0
- package/dist/verify-env/agent-hook-readiness.js +150 -0
- package/dist/verify-env/agent-hooks-live-probe.d.ts +16 -4
- package/dist/verify-env/agent-hooks-live-probe.js +120 -107
- package/dist/verify-env/agent-hooks.js +11 -3
- package/dist/verify-env/index.d.ts +1 -0
- package/dist/verify-env/index.js +1 -0
- package/package.json +7 -3
package/dist/policy/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { FIELD_DELIVERY_BRANCH, FIELD_DELIVERY_BRANCH_CLI_ALIAS, inspectDelivery
|
|
|
4
4
|
import { FIELD_HOST_HOOKS, FIELD_HOST_HOOKS_CLI_ALIAS, inspectHostHooks } from "./host-hooks.js";
|
|
5
5
|
import { FIELD_HOST_SLASH_COMMANDS, FIELD_HOST_SLASH_COMMANDS_CLI_ALIAS, inspectHostSlashCommands, } from "./host-slash-commands.js";
|
|
6
6
|
import { FIELD_HOTFIX_CRITERIA, FIELD_HOTFIX_CRITERIA_CLI_ALIAS, inspectHotfixCriteria, } from "./hotfix-criteria.js";
|
|
7
|
+
import { FIELD_MIN_GREPTILE_CONFIDENCE, FIELD_MIN_GREPTILE_CONFIDENCE_CLI_ALIAS, inspectMinGreptileConfidence, } from "./min-greptile-confidence.js";
|
|
7
8
|
import { readPlanPolicy } from "./plan-extensions.js";
|
|
8
9
|
import { FIELD_PRODUCT_SIGNAL, FIELD_PRODUCT_SIGNAL_CLI_ALIAS, inspectProductSignal, } from "./product-signal.js";
|
|
9
10
|
import { FIELD_REQUIRE_HUMAN_MERGE, FIELD_REQUIRE_HUMAN_MERGE_CLI_ALIAS, inspectRequireHumanMerge, } from "./require-human-merge.js";
|
|
@@ -23,6 +24,7 @@ export * from "./host-hooks.js";
|
|
|
23
24
|
export * from "./host-slash-commands.js";
|
|
24
25
|
export * from "./hotfix-criteria.js";
|
|
25
26
|
export * from "./intent-ceiling.js";
|
|
27
|
+
export * from "./min-greptile-confidence.js";
|
|
26
28
|
export * from "./no-deft-directive.js";
|
|
27
29
|
export * from "./org-force-on-migration.js";
|
|
28
30
|
export * from "./plan-extensions.js";
|
|
@@ -44,6 +46,7 @@ export const FIELD_TRIAGE_SCOPE_IGNORES = "plan.policy.triageScopeIgnores";
|
|
|
44
46
|
export const FIELD_TRIAGE_RANKING_LABELS = "plan.policy.triageRankingLabels";
|
|
45
47
|
export const FIELD_TRIAGE_AUTO_CLASSIFY = "plan.policy.triageAutoClassify";
|
|
46
48
|
export const FIELD_TRIAGE_HOLD_MARKERS = "plan.policy.triageHoldMarkers";
|
|
49
|
+
export const FIELD_TRIAGE_LABEL_MIRROR = "plan.policy.triageLabelMirror";
|
|
47
50
|
export const FIELD_SWARM_SUBAGENT_BACKEND = "plan.policy.swarmSubagentBackend";
|
|
48
51
|
// deliveryBranch also exported from delivery-branch.js via export *
|
|
49
52
|
export const DEFAULT_SESSION_RITUAL_STALENESS_HOURS = 4;
|
|
@@ -53,6 +56,13 @@ export const DEFAULT_TRIAGE_SCOPE_VALUE = [
|
|
|
53
56
|
export const DEFAULT_TRIAGE_SCOPE_IGNORES_VALUE = [];
|
|
54
57
|
export const DEFAULT_TRIAGE_RANKING_LABELS_VALUE = [];
|
|
55
58
|
export const DEFAULT_TRIAGE_AUTO_CLASSIFY_VALUE = [];
|
|
59
|
+
/** Default for #1423 Tier-1 label mirror: enabled with `triaged` idempotency marker. */
|
|
60
|
+
export const DEFAULT_TRIAGE_LABEL_MIRROR_VALUE = {
|
|
61
|
+
enabled: true,
|
|
62
|
+
idempotencyLabel: "triaged",
|
|
63
|
+
alwaysLabels: ["triaged"],
|
|
64
|
+
actionLabels: {},
|
|
65
|
+
};
|
|
56
66
|
export const KNOWN_SUBAGENT_BACKEND_IDS = new Set(["composer", "cursor-cloud", "grok-build"]);
|
|
57
67
|
const FALLBACK_HOLD_MARKERS = [
|
|
58
68
|
"do not implement",
|
|
@@ -137,6 +147,32 @@ function inspectWipCap(data) {
|
|
|
137
147
|
source: "default",
|
|
138
148
|
};
|
|
139
149
|
}
|
|
150
|
+
function inspectTriageLabelMirrorField(data) {
|
|
151
|
+
const policyBlock = getPolicyBlock(data);
|
|
152
|
+
if ("triageLabelMirror" in policyBlock) {
|
|
153
|
+
const raw = policyBlock.triageLabelMirror;
|
|
154
|
+
if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
|
|
155
|
+
return {
|
|
156
|
+
name: FIELD_TRIAGE_LABEL_MIRROR,
|
|
157
|
+
current: raw,
|
|
158
|
+
default: { ...DEFAULT_TRIAGE_LABEL_MIRROR_VALUE },
|
|
159
|
+
source: "typed",
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
name: FIELD_TRIAGE_LABEL_MIRROR,
|
|
164
|
+
current: { ...DEFAULT_TRIAGE_LABEL_MIRROR_VALUE },
|
|
165
|
+
default: { ...DEFAULT_TRIAGE_LABEL_MIRROR_VALUE },
|
|
166
|
+
source: "default-on-error",
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
name: FIELD_TRIAGE_LABEL_MIRROR,
|
|
171
|
+
current: { ...DEFAULT_TRIAGE_LABEL_MIRROR_VALUE },
|
|
172
|
+
default: { ...DEFAULT_TRIAGE_LABEL_MIRROR_VALUE },
|
|
173
|
+
source: "default",
|
|
174
|
+
};
|
|
175
|
+
}
|
|
140
176
|
function inspectSessionRitualStalenessHours(data) {
|
|
141
177
|
const policyBlock = getPolicyBlock(data);
|
|
142
178
|
if ("sessionRitualStalenessHours" in policyBlock) {
|
|
@@ -340,6 +376,15 @@ function inspectDeliveryBranchField(data, projectRoot) {
|
|
|
340
376
|
source: field.source,
|
|
341
377
|
};
|
|
342
378
|
}
|
|
379
|
+
function inspectMinGreptileConfidenceField(data, projectRoot) {
|
|
380
|
+
const field = inspectMinGreptileConfidence(data, projectRoot);
|
|
381
|
+
return {
|
|
382
|
+
name: field.name,
|
|
383
|
+
current: field.current,
|
|
384
|
+
default: field.default,
|
|
385
|
+
source: field.source,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
343
388
|
const REGISTERED_POLICIES = [
|
|
344
389
|
inspectAllowDirectCommits,
|
|
345
390
|
inspectWipCap,
|
|
@@ -351,8 +396,10 @@ const REGISTERED_POLICIES = [
|
|
|
351
396
|
(data) => listFieldInspector(data, "triageHoldMarkers", FIELD_TRIAGE_HOLD_MARKERS, defaultHoldMarkers(), {
|
|
352
397
|
emptyIsTyped: true,
|
|
353
398
|
}),
|
|
399
|
+
inspectTriageLabelMirrorField,
|
|
354
400
|
inspectSwarmSubagentBackend,
|
|
355
401
|
inspectDeliveryBranchField,
|
|
402
|
+
inspectMinGreptileConfidenceField,
|
|
356
403
|
inspectHostHooksField,
|
|
357
404
|
inspectHostSlashCommandsField,
|
|
358
405
|
inspectOpenClawProductCommandsField,
|
|
@@ -393,7 +440,9 @@ export function inspectOnePolicy(name, projectRoot) {
|
|
|
393
440
|
? FIELD_HOTFIX_CRITERIA
|
|
394
441
|
: name === FIELD_DELIVERY_BRANCH_CLI_ALIAS
|
|
395
442
|
? FIELD_DELIVERY_BRANCH
|
|
396
|
-
: name
|
|
443
|
+
: name === FIELD_MIN_GREPTILE_CONFIDENCE_CLI_ALIAS
|
|
444
|
+
? FIELD_MIN_GREPTILE_CONFIDENCE
|
|
445
|
+
: name;
|
|
397
446
|
for (const field of inspectAllPolicies(projectRoot)) {
|
|
398
447
|
if (field.name === normalized)
|
|
399
448
|
return field;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed plan.policy.review.minGreptileConfidence (#3095).
|
|
3
|
+
*
|
|
4
|
+
* CLEAN / merge-ready require Greptile confidence >= min (score out of 5).
|
|
5
|
+
* Resolution order: explicit project policy > framework dogfood detect > consumer default.
|
|
6
|
+
*
|
|
7
|
+
* - Consumer default: 4 (legacy bar confidence > 3, i.e. 4/5 or 5/5)
|
|
8
|
+
* - Directive dogfood (framework source checkout): 5 (5/5 required)
|
|
9
|
+
*/
|
|
10
|
+
/** Canonical dotted path for policy:show / PROJECT-DEFINITION. */
|
|
11
|
+
export declare const FIELD_MIN_GREPTILE_CONFIDENCE = "plan.policy.review.minGreptileConfidence";
|
|
12
|
+
/** CLI alias for `task policy:show --field=minGreptileConfidence`. */
|
|
13
|
+
export declare const FIELD_MIN_GREPTILE_CONFIDENCE_CLI_ALIAS = "minGreptileConfidence";
|
|
14
|
+
/**
|
|
15
|
+
* Consumer default minimum confidence that still CLEANs (#3095).
|
|
16
|
+
* Matches the historical gate `confidence > 3` (i.e. score >= 4).
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE = 4;
|
|
19
|
+
/** Directive dogfood bar: CLEAN requires confidence == 5/5. */
|
|
20
|
+
export declare const DOGFOOD_MIN_GREPTILE_CONFIDENCE = 5;
|
|
21
|
+
export declare const MIN_GREPTILE_CONFIDENCE_FLOOR = 1;
|
|
22
|
+
export declare const MIN_GREPTILE_CONFIDENCE_CEILING = 5;
|
|
23
|
+
export type MinGreptileConfidenceSource = "typed" | "dogfood" | "default" | "default-on-error";
|
|
24
|
+
export interface MinGreptileConfidenceResolved {
|
|
25
|
+
/** Minimum score (1–5) that satisfies CLEAN; score must be >= min. */
|
|
26
|
+
readonly min: number;
|
|
27
|
+
readonly source: MinGreptileConfidenceSource;
|
|
28
|
+
readonly error: string | null;
|
|
29
|
+
}
|
|
30
|
+
/** True when score is present and meets the minimum floor. */
|
|
31
|
+
export declare function meetsMinGreptileConfidence(confidence: number | null | undefined, min: number): boolean;
|
|
32
|
+
/** Human-facing phrase for the active bar (legacy "> 3" when min is 4). */
|
|
33
|
+
export declare function formatMinConfidenceRequirement(min: number): string;
|
|
34
|
+
/** Validate a raw integer-ish min confidence value. */
|
|
35
|
+
export declare function validateMinGreptileConfidence(raw: unknown): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Read nested plan.policy.review.minGreptileConfidence from a policy block.
|
|
38
|
+
* Returns undefined when the key is absent.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readMinGreptileConfidenceFromPolicyBlock(policyBlock: unknown): unknown | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve min Greptile confidence for CLEAN gates (#3095).
|
|
43
|
+
*
|
|
44
|
+
* 1. Explicit typed plan.policy.review.minGreptileConfidence
|
|
45
|
+
* 2. Framework dogfood detection (framework source repo root) → 5
|
|
46
|
+
* 3. Consumer default → 4
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveMinGreptileConfidence(projectRoot?: string | null): MinGreptileConfidenceResolved;
|
|
49
|
+
export interface MinGreptileConfidencePolicyField {
|
|
50
|
+
readonly name: typeof FIELD_MIN_GREPTILE_CONFIDENCE;
|
|
51
|
+
readonly current: number;
|
|
52
|
+
readonly default: number;
|
|
53
|
+
readonly source: string;
|
|
54
|
+
}
|
|
55
|
+
/** Inspector row for `task policy:show --field=minGreptileConfidence` (#3095). */
|
|
56
|
+
export declare function inspectMinGreptileConfidence(_data: Record<string, unknown> | null, projectRoot?: string): MinGreptileConfidencePolicyField;
|
|
57
|
+
//# sourceMappingURL=min-greptile-confidence.d.ts.map
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed plan.policy.review.minGreptileConfidence (#3095).
|
|
3
|
+
*
|
|
4
|
+
* CLEAN / merge-ready require Greptile confidence >= min (score out of 5).
|
|
5
|
+
* Resolution order: explicit project policy > framework dogfood detect > consumer default.
|
|
6
|
+
*
|
|
7
|
+
* - Consumer default: 4 (legacy bar confidence > 3, i.e. 4/5 or 5/5)
|
|
8
|
+
* - Directive dogfood (framework source checkout): 5 (5/5 required)
|
|
9
|
+
*/
|
|
10
|
+
import { isFrameworkRepoRoot } from "../check/context.js";
|
|
11
|
+
import { readPlanPolicy } from "./plan-extensions.js";
|
|
12
|
+
import { loadProjectDefinition } from "./resolve.js";
|
|
13
|
+
/** Canonical dotted path for policy:show / PROJECT-DEFINITION. */
|
|
14
|
+
export const FIELD_MIN_GREPTILE_CONFIDENCE = "plan.policy.review.minGreptileConfidence";
|
|
15
|
+
/** CLI alias for `task policy:show --field=minGreptileConfidence`. */
|
|
16
|
+
export const FIELD_MIN_GREPTILE_CONFIDENCE_CLI_ALIAS = "minGreptileConfidence";
|
|
17
|
+
/**
|
|
18
|
+
* Consumer default minimum confidence that still CLEANs (#3095).
|
|
19
|
+
* Matches the historical gate `confidence > 3` (i.e. score >= 4).
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE = 4;
|
|
22
|
+
/** Directive dogfood bar: CLEAN requires confidence == 5/5. */
|
|
23
|
+
export const DOGFOOD_MIN_GREPTILE_CONFIDENCE = 5;
|
|
24
|
+
export const MIN_GREPTILE_CONFIDENCE_FLOOR = 1;
|
|
25
|
+
export const MIN_GREPTILE_CONFIDENCE_CEILING = 5;
|
|
26
|
+
function defaultResolved(source, min, error = null) {
|
|
27
|
+
return { min, source, error };
|
|
28
|
+
}
|
|
29
|
+
/** True when score is present and meets the minimum floor. */
|
|
30
|
+
export function meetsMinGreptileConfidence(confidence, min) {
|
|
31
|
+
if (confidence === null || confidence === undefined) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return confidence >= min;
|
|
35
|
+
}
|
|
36
|
+
/** Human-facing phrase for the active bar (legacy "> 3" when min is 4). */
|
|
37
|
+
export function formatMinConfidenceRequirement(min) {
|
|
38
|
+
if (min === DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE) {
|
|
39
|
+
return `> ${min - 1} (i.e. ${min}/5+)`;
|
|
40
|
+
}
|
|
41
|
+
return `>= ${min}/5`;
|
|
42
|
+
}
|
|
43
|
+
/** Validate a raw integer-ish min confidence value. */
|
|
44
|
+
export function validateMinGreptileConfidence(raw) {
|
|
45
|
+
if (typeof raw !== "number" || !Number.isInteger(raw)) {
|
|
46
|
+
return `${FIELD_MIN_GREPTILE_CONFIDENCE} must be an integer ${MIN_GREPTILE_CONFIDENCE_FLOOR}–${MIN_GREPTILE_CONFIDENCE_CEILING}; got ${typeof raw}`;
|
|
47
|
+
}
|
|
48
|
+
if (raw < MIN_GREPTILE_CONFIDENCE_FLOOR || raw > MIN_GREPTILE_CONFIDENCE_CEILING) {
|
|
49
|
+
return `${FIELD_MIN_GREPTILE_CONFIDENCE} must be between ${MIN_GREPTILE_CONFIDENCE_FLOOR} and ${MIN_GREPTILE_CONFIDENCE_CEILING}; got ${raw}`;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Read nested plan.policy.review.minGreptileConfidence from a policy block.
|
|
55
|
+
* Returns undefined when the key is absent.
|
|
56
|
+
*/
|
|
57
|
+
export function readMinGreptileConfidenceFromPolicyBlock(policyBlock) {
|
|
58
|
+
if (typeof policyBlock !== "object" || policyBlock === null || Array.isArray(policyBlock)) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
const rec = policyBlock;
|
|
62
|
+
if (!("review" in rec)) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const review = rec.review;
|
|
66
|
+
if (typeof review !== "object" || review === null || Array.isArray(review)) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
const reviewRec = review;
|
|
70
|
+
if (!("minGreptileConfidence" in reviewRec)) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return reviewRec.minGreptileConfidence;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolve min Greptile confidence for CLEAN gates (#3095).
|
|
77
|
+
*
|
|
78
|
+
* 1. Explicit typed plan.policy.review.minGreptileConfidence
|
|
79
|
+
* 2. Framework dogfood detection (framework source repo root) → 5
|
|
80
|
+
* 3. Consumer default → 4
|
|
81
|
+
*/
|
|
82
|
+
export function resolveMinGreptileConfidence(projectRoot) {
|
|
83
|
+
if (projectRoot !== undefined && projectRoot !== null && projectRoot.length > 0) {
|
|
84
|
+
const [data, err] = loadProjectDefinition(projectRoot);
|
|
85
|
+
if (data !== null) {
|
|
86
|
+
const policyBlock = readPlanPolicy(data.plan);
|
|
87
|
+
const raw = readMinGreptileConfidenceFromPolicyBlock(policyBlock);
|
|
88
|
+
if (raw !== undefined) {
|
|
89
|
+
const validationError = validateMinGreptileConfidence(raw);
|
|
90
|
+
if (validationError !== null) {
|
|
91
|
+
// Invalid typed value: fall through to dogfood/default with error recorded.
|
|
92
|
+
if (isFrameworkRepoRoot(projectRoot)) {
|
|
93
|
+
return defaultResolved("dogfood", DOGFOOD_MIN_GREPTILE_CONFIDENCE, validationError);
|
|
94
|
+
}
|
|
95
|
+
return defaultResolved("default-on-error", DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE, validationError);
|
|
96
|
+
}
|
|
97
|
+
return defaultResolved("typed", raw, null);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else if (err !== null && err.length > 0) {
|
|
101
|
+
// Missing PROJECT-DEFINITION is not fatal; dogfood/default still apply.
|
|
102
|
+
if (isFrameworkRepoRoot(projectRoot)) {
|
|
103
|
+
return defaultResolved("dogfood", DOGFOOD_MIN_GREPTILE_CONFIDENCE, null);
|
|
104
|
+
}
|
|
105
|
+
return defaultResolved("default", DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE, err);
|
|
106
|
+
}
|
|
107
|
+
if (isFrameworkRepoRoot(projectRoot)) {
|
|
108
|
+
return defaultResolved("dogfood", DOGFOOD_MIN_GREPTILE_CONFIDENCE, null);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return defaultResolved("default", DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE, null);
|
|
112
|
+
}
|
|
113
|
+
/** Inspector row for `task policy:show --field=minGreptileConfidence` (#3095). */
|
|
114
|
+
export function inspectMinGreptileConfidence(_data, projectRoot) {
|
|
115
|
+
const resolved = resolveMinGreptileConfidence(projectRoot);
|
|
116
|
+
return {
|
|
117
|
+
name: FIELD_MIN_GREPTILE_CONFIDENCE,
|
|
118
|
+
current: resolved.min,
|
|
119
|
+
default: DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE,
|
|
120
|
+
source: resolved.source,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=min-greptile-confidence.js.map
|
|
@@ -4,7 +4,7 @@ import { type InlineGreptileFindings } from "./greptile-inline.js";
|
|
|
4
4
|
import { type MergeabilitySignal } from "./mergeability.js";
|
|
5
5
|
import type { SlizardGateOptions } from "./slizard-gate.js";
|
|
6
6
|
import type { GateResult, RunGhFn } from "./types.js";
|
|
7
|
-
declare function buildGateResult(prNumber: number, repo: string | null, headSha: string | null, body: string, via: string, partialData?: Record<string, unknown>, error?: string | null, inline?: InlineGreptileFindings | null): GateResult;
|
|
7
|
+
declare function buildGateResult(prNumber: number, repo: string | null, headSha: string | null, body: string, via: string, partialData?: Record<string, unknown>, error?: string | null, inline?: InlineGreptileFindings | null, minConfidence?: number): GateResult;
|
|
8
8
|
/** Injectable GitHub-mergeability read seam (#2260) — keeps unit tests hermetic. */
|
|
9
9
|
export type FetchMergeabilityFn = (prNumber: number, repo: string, runGh: RunGhFn) => MergeabilitySignal;
|
|
10
10
|
export interface ComputeGateOptions extends CiGateOptions, SlizardGateOptions {
|
|
@@ -15,6 +15,16 @@ export interface ComputeGateOptions extends CiGateOptions, SlizardGateOptions {
|
|
|
15
15
|
* off, an absent/stale review verdict blocks even on a GitHub-CLEAN PR.
|
|
16
16
|
*/
|
|
17
17
|
readonly disableMergeabilityReconcile?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Project root for resolving plan.policy.review.minGreptileConfidence (#3095).
|
|
20
|
+
* Defaults to process.cwd() when omitted.
|
|
21
|
+
*/
|
|
22
|
+
readonly projectRoot?: string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Override the resolved min confidence (1–5). When set, skips policy resolve.
|
|
25
|
+
* Tests and injectors use this; production callers leave it unset.
|
|
26
|
+
*/
|
|
27
|
+
readonly minConfidence?: number;
|
|
18
28
|
}
|
|
19
29
|
/** Run the primary->fallback1->fallback2 cascade and return a result. */
|
|
20
30
|
export declare function computeGateResult(prNumber: number, repo: string | null, runGh: RunGhFn, options?: ComputeGateOptions): GateResult;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveMinGreptileConfidence } from "../policy/min-greptile-confidence.js";
|
|
1
2
|
import { buildCiSummaryLine, evaluateCiGate } from "./ci-gate.js";
|
|
2
3
|
import { FALLBACK2_NOT_CLEAN_MSG, VIA_ERROR, VIA_FALLBACK1, VIA_FALLBACK2, VIA_PRIMARY, } from "./constants.js";
|
|
3
4
|
import { evaluateGates, isMergeReady } from "./evaluate.js";
|
|
@@ -6,9 +7,11 @@ import { fetchUnresolvedGreptileInlineFindings, inlineFindingsToDict, } from "./
|
|
|
6
7
|
import { fetchMergeability, isGithubMergeableClean, mergeabilityToDict, verdictBlockIsSoftOnly, verdictShaIsStale, } from "./mergeability.js";
|
|
7
8
|
import { emptyVerdict, parseGreptileBody } from "./parse.js";
|
|
8
9
|
import { evaluateSlizardGate, isSlizardCheck } from "./slizard-gate.js";
|
|
9
|
-
function buildGateResult(prNumber, repo, headSha, body, via, partialData = {}, error = null, inline = null) {
|
|
10
|
+
function buildGateResult(prNumber, repo, headSha, body, via, partialData = {}, error = null, inline = null, minConfidence) {
|
|
10
11
|
const verdict = parseGreptileBody(body);
|
|
11
|
-
const failures = evaluateGates(prNumber, headSha, verdict, inline
|
|
12
|
+
const failures = evaluateGates(prNumber, headSha, verdict, inline, {
|
|
13
|
+
minConfidence,
|
|
14
|
+
});
|
|
12
15
|
return {
|
|
13
16
|
prNumber,
|
|
14
17
|
repo,
|
|
@@ -20,6 +23,12 @@ function buildGateResult(prNumber, repo, headSha, body, via, partialData = {}, e
|
|
|
20
23
|
error,
|
|
21
24
|
};
|
|
22
25
|
}
|
|
26
|
+
function resolvedMinConfidence(options) {
|
|
27
|
+
if (options.minConfidence !== undefined) {
|
|
28
|
+
return options.minConfidence;
|
|
29
|
+
}
|
|
30
|
+
return resolveMinGreptileConfidence(options.projectRoot ?? process.cwd()).min;
|
|
31
|
+
}
|
|
23
32
|
/** Run the CI + SLizard gates off a single check-runs fetch (#2169 / #2189). */
|
|
24
33
|
function evaluateCiAndSlizard(checkRuns, options) {
|
|
25
34
|
const slizardResult = evaluateSlizardGate(checkRuns, options);
|
|
@@ -110,7 +119,11 @@ function finalizeVerdictGate(prNumber, repo, headSha, verdict, runGh, options) {
|
|
|
110
119
|
const resolved = resolveRepo(repo, runGh);
|
|
111
120
|
const inline = loadInlineGreptileFindings(prNumber, repo, headSha, runGh);
|
|
112
121
|
partialData.greptile_inline = inlineFindingsToDict(inline);
|
|
113
|
-
const
|
|
122
|
+
const minConfidence = resolvedMinConfidence(options);
|
|
123
|
+
partialData.min_greptile_confidence = minConfidence;
|
|
124
|
+
const failures = evaluateGates(prNumber, headSha, verdict, inline, {
|
|
125
|
+
minConfidence,
|
|
126
|
+
});
|
|
114
127
|
if (failures.length === 0) {
|
|
115
128
|
const ci = applyCiGateForHead(resolved.repo, headSha, runGh, options);
|
|
116
129
|
failures.push(...ci.failures);
|
|
@@ -123,7 +136,7 @@ function finalizeVerdictGate(prNumber, repo, headSha, verdict, runGh, options) {
|
|
|
123
136
|
// blocking. Only reconcile a SOFT block (verdict absent / stale head SHA).
|
|
124
137
|
if (options.disableMergeabilityReconcile === true ||
|
|
125
138
|
resolved.repo === null ||
|
|
126
|
-
!verdictBlockIsSoftOnly(verdict, headSha, inline)) {
|
|
139
|
+
!verdictBlockIsSoftOnly(verdict, headSha, inline, minConfidence)) {
|
|
127
140
|
return { failures, partialData };
|
|
128
141
|
}
|
|
129
142
|
const ci = applyCiGateForHead(resolved.repo, headSha, runGh, options);
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { InlineGreptileFindings } from "./greptile-inline.js";
|
|
2
2
|
import type { GreptileVerdict } from "./types.js";
|
|
3
|
+
export interface EvaluateGatesOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Minimum Greptile confidence (1–5) that satisfies CLEAN (#3095).
|
|
6
|
+
* Defaults to the consumer bar (4 == legacy confidence > 3).
|
|
7
|
+
*/
|
|
8
|
+
readonly minConfidence?: number;
|
|
9
|
+
}
|
|
3
10
|
/** Return failure messages (empty list == merge-ready). */
|
|
4
|
-
export declare function evaluateGates(_prNumber: number, headSha: string | null, verdict: GreptileVerdict, inline?: InlineGreptileFindings | null): string[];
|
|
11
|
+
export declare function evaluateGates(_prNumber: number, headSha: string | null, verdict: GreptileVerdict, inline?: InlineGreptileFindings | null, options?: EvaluateGatesOptions): string[];
|
|
5
12
|
export declare function isMergeReady(failures: readonly string[]): boolean;
|
|
6
13
|
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE, formatMinConfidenceRequirement, meetsMinGreptileConfidence, } from "../policy/min-greptile-confidence.js";
|
|
1
2
|
import { INFORMAL_CLEAN_DIAGNOSTIC } from "./constants.js";
|
|
2
3
|
/** Return failure messages (empty list == merge-ready). */
|
|
3
|
-
export function evaluateGates(_prNumber, headSha, verdict, inline = null) {
|
|
4
|
+
export function evaluateGates(_prNumber, headSha, verdict, inline = null, options = {}) {
|
|
4
5
|
const failures = [];
|
|
6
|
+
const minConfidence = options.minConfidence ?? DEFAULT_CONSUMER_MIN_GREPTILE_CONFIDENCE;
|
|
5
7
|
if (!verdict.found) {
|
|
6
8
|
failures.push("No Greptile rolling-summary comment found on the PR. " +
|
|
7
9
|
"Either Greptile has not posted yet, or the bot login filter is wrong. " +
|
|
@@ -32,9 +34,10 @@ export function evaluateGates(_prNumber, headSha, verdict, inline = null) {
|
|
|
32
34
|
"Confidence is a required exit-condition input per " +
|
|
33
35
|
"skills/deft-directive-review-cycle/SKILL.md Phase 2 Step 6.");
|
|
34
36
|
}
|
|
35
|
-
else if (verdict.confidence
|
|
36
|
-
failures.push(`Greptile confidence is ${verdict.confidence}/5; exit condition requires
|
|
37
|
-
"Address remaining findings or push clarifying changes."
|
|
37
|
+
else if (!meetsMinGreptileConfidence(verdict.confidence, minConfidence)) {
|
|
38
|
+
failures.push(`Greptile confidence is ${verdict.confidence}/5; exit condition requires ${formatMinConfidenceRequirement(minConfidence)}. ` +
|
|
39
|
+
"Address remaining findings or push clarifying changes. " +
|
|
40
|
+
"Inspect the floor via `task policy:show --field=minGreptileConfidence` (#3095).");
|
|
38
41
|
}
|
|
39
42
|
if (verdict.p0Count > 0 || verdict.p1Count > 0) {
|
|
40
43
|
failures.push(`Greptile reports ${verdict.p0Count} P0 and ${verdict.p1Count} P1 findings ` +
|
|
@@ -42,5 +42,11 @@ export declare function verdictShaIsStale(verdict: GreptileVerdict, headSha: str
|
|
|
42
42
|
* regardless of GitHub mergeability (guardrail: do not merge a PR with a real
|
|
43
43
|
* P0/P1 review finding).
|
|
44
44
|
*/
|
|
45
|
-
export declare function verdictBlockIsSoftOnly(verdict: GreptileVerdict, headSha: string | null, inline?: InlineGreptileFindings | null
|
|
45
|
+
export declare function verdictBlockIsSoftOnly(verdict: GreptileVerdict, headSha: string | null, inline?: InlineGreptileFindings | null,
|
|
46
|
+
/**
|
|
47
|
+
* Resolved min Greptile confidence (1–5). Scores below this are HARD blockers
|
|
48
|
+
* and must never be reconciled away via GitHub CLEAN (#3095). Defaults to the
|
|
49
|
+
* consumer floor (4).
|
|
50
|
+
*/
|
|
51
|
+
minConfidence?: number): boolean;
|
|
46
52
|
//# sourceMappingURL=mergeability.d.ts.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { meetsMinGreptileConfidence } from "../policy/min-greptile-confidence.js";
|
|
1
2
|
/** REST `mergeable_state` value that mirrors GraphQL `mergeStateStatus: CLEAN`. */
|
|
2
3
|
export const MERGE_STATE_CLEAN = "clean";
|
|
3
4
|
/**
|
|
@@ -75,7 +76,13 @@ export function verdictShaIsStale(verdict, headSha) {
|
|
|
75
76
|
* regardless of GitHub mergeability (guardrail: do not merge a PR with a real
|
|
76
77
|
* P0/P1 review finding).
|
|
77
78
|
*/
|
|
78
|
-
export function verdictBlockIsSoftOnly(verdict, headSha, inline = null
|
|
79
|
+
export function verdictBlockIsSoftOnly(verdict, headSha, inline = null,
|
|
80
|
+
/**
|
|
81
|
+
* Resolved min Greptile confidence (1–5). Scores below this are HARD blockers
|
|
82
|
+
* and must never be reconciled away via GitHub CLEAN (#3095). Defaults to the
|
|
83
|
+
* consumer floor (4).
|
|
84
|
+
*/
|
|
85
|
+
minConfidence = 4) {
|
|
79
86
|
if (inline !== null && inline.error !== null) {
|
|
80
87
|
return false;
|
|
81
88
|
}
|
|
@@ -99,7 +106,12 @@ export function verdictBlockIsSoftOnly(verdict, headSha, inline = null) {
|
|
|
99
106
|
if (verdict.errored) {
|
|
100
107
|
return false;
|
|
101
108
|
}
|
|
102
|
-
|
|
109
|
+
// Confidence below the resolved floor is a hard blocker (#2260 / #3095).
|
|
110
|
+
// Dogfood/policy may set min=5 so a 4/5 score stays hard even when GitHub
|
|
111
|
+
// reports CLEAN + MERGEABLE. Use the shared predicate so the export is on
|
|
112
|
+
// the production call path (SLizard #3095).
|
|
113
|
+
if (verdict.confidence !== null &&
|
|
114
|
+
!meetsMinGreptileConfidence(verdict.confidence, minConfidence)) {
|
|
103
115
|
return false;
|
|
104
116
|
}
|
|
105
117
|
if (verdict.p0Count > 0 || verdict.p1Count > 0) {
|
|
@@ -5,6 +5,8 @@ export interface ParsedMonitorArgs {
|
|
|
5
5
|
readonly repo: string | null;
|
|
6
6
|
readonly capMinutes: number;
|
|
7
7
|
readonly emitJson: boolean;
|
|
8
|
+
/** Project root for minGreptileConfidence (#3095 / #3102). Null = default cwd at run. */
|
|
9
|
+
readonly projectRoot: string | null;
|
|
8
10
|
readonly error?: string;
|
|
9
11
|
}
|
|
10
12
|
export declare function parseMonitorArgs(argv: readonly string[]): ParsedMonitorArgs;
|
package/dist/pr-monitor/main.js
CHANGED
|
@@ -13,6 +13,7 @@ export function parseMonitorArgs(argv) {
|
|
|
13
13
|
let repo = null;
|
|
14
14
|
let capMinutes = 60;
|
|
15
15
|
let emitJson = false;
|
|
16
|
+
let projectRoot = null;
|
|
16
17
|
for (let i = 0; i < argv.length; i += 1) {
|
|
17
18
|
const arg = argv[i];
|
|
18
19
|
if (arg === "--json") {
|
|
@@ -26,6 +27,7 @@ export function parseMonitorArgs(argv) {
|
|
|
26
27
|
repo,
|
|
27
28
|
capMinutes,
|
|
28
29
|
emitJson,
|
|
30
|
+
projectRoot,
|
|
29
31
|
error: "argument --repo: expected one argument",
|
|
30
32
|
};
|
|
31
33
|
}
|
|
@@ -35,6 +37,24 @@ export function parseMonitorArgs(argv) {
|
|
|
35
37
|
else if (arg?.startsWith("--repo=")) {
|
|
36
38
|
repo = arg.slice("--repo=".length);
|
|
37
39
|
}
|
|
40
|
+
else if (arg === "--project-root") {
|
|
41
|
+
const value = argv[i + 1];
|
|
42
|
+
if (value === undefined) {
|
|
43
|
+
return {
|
|
44
|
+
prNumber,
|
|
45
|
+
repo,
|
|
46
|
+
capMinutes,
|
|
47
|
+
emitJson,
|
|
48
|
+
projectRoot,
|
|
49
|
+
error: "argument --project-root: expected one argument",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
projectRoot = value;
|
|
53
|
+
i += 1;
|
|
54
|
+
}
|
|
55
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
56
|
+
projectRoot = arg.slice("--project-root=".length);
|
|
57
|
+
}
|
|
38
58
|
else if (arg === "--cap-minutes") {
|
|
39
59
|
const value = argv[i + 1];
|
|
40
60
|
if (value === undefined) {
|
|
@@ -43,6 +63,7 @@ export function parseMonitorArgs(argv) {
|
|
|
43
63
|
repo,
|
|
44
64
|
capMinutes,
|
|
45
65
|
emitJson,
|
|
66
|
+
projectRoot,
|
|
46
67
|
error: "argument --cap-minutes: expected one argument",
|
|
47
68
|
};
|
|
48
69
|
}
|
|
@@ -53,6 +74,7 @@ export function parseMonitorArgs(argv) {
|
|
|
53
74
|
repo,
|
|
54
75
|
capMinutes,
|
|
55
76
|
emitJson,
|
|
77
|
+
projectRoot,
|
|
56
78
|
error: `invalid --cap-minutes value: ${value}`,
|
|
57
79
|
};
|
|
58
80
|
}
|
|
@@ -68,6 +90,7 @@ export function parseMonitorArgs(argv) {
|
|
|
68
90
|
repo,
|
|
69
91
|
capMinutes,
|
|
70
92
|
emitJson,
|
|
93
|
+
projectRoot,
|
|
71
94
|
error: `invalid --cap-minutes value: ${value}`,
|
|
72
95
|
};
|
|
73
96
|
}
|
|
@@ -79,6 +102,7 @@ export function parseMonitorArgs(argv) {
|
|
|
79
102
|
repo,
|
|
80
103
|
capMinutes,
|
|
81
104
|
emitJson,
|
|
105
|
+
projectRoot,
|
|
82
106
|
error: `unrecognized arguments: ${arg}`,
|
|
83
107
|
};
|
|
84
108
|
}
|
|
@@ -90,6 +114,7 @@ export function parseMonitorArgs(argv) {
|
|
|
90
114
|
repo,
|
|
91
115
|
capMinutes,
|
|
92
116
|
emitJson,
|
|
117
|
+
projectRoot,
|
|
93
118
|
error: `invalid PR number: ${arg}`,
|
|
94
119
|
};
|
|
95
120
|
}
|
|
@@ -101,6 +126,7 @@ export function parseMonitorArgs(argv) {
|
|
|
101
126
|
repo,
|
|
102
127
|
capMinutes,
|
|
103
128
|
emitJson,
|
|
129
|
+
projectRoot,
|
|
104
130
|
error: `unrecognized arguments: ${arg}`,
|
|
105
131
|
};
|
|
106
132
|
}
|
|
@@ -111,10 +137,11 @@ export function parseMonitorArgs(argv) {
|
|
|
111
137
|
repo,
|
|
112
138
|
capMinutes,
|
|
113
139
|
emitJson,
|
|
140
|
+
projectRoot,
|
|
114
141
|
error: "the following arguments are required: pr_number",
|
|
115
142
|
};
|
|
116
143
|
}
|
|
117
|
-
return { prNumber, repo, capMinutes, emitJson };
|
|
144
|
+
return { prNumber, repo, capMinutes, emitJson, projectRoot };
|
|
118
145
|
}
|
|
119
146
|
export function runMonitor(argv, options = {}) {
|
|
120
147
|
const args = parseMonitorArgs(argv);
|
|
@@ -131,6 +158,9 @@ export function runMonitor(argv, options = {}) {
|
|
|
131
158
|
const { exitCode, payload, pollCount } = monitorFn(args.prNumber, repo, {
|
|
132
159
|
capMinutes: args.capMinutes,
|
|
133
160
|
runGh: options.runGh,
|
|
161
|
+
// CLI --project-root or cwd: production remote-monitor path must not silently
|
|
162
|
+
// resolve minGreptileConfidence from an unrelated cwd (#3095 residual / #3102).
|
|
163
|
+
projectRoot: args.projectRoot ?? process.cwd(),
|
|
134
164
|
});
|
|
135
165
|
const summaryLabel = summaryLabelForExit(exitCode);
|
|
136
166
|
const via = typeof payload.via === "string" ? payload.via : "?";
|
|
@@ -125,7 +125,11 @@ export function monitor(prNumber, repo, options = {}) {
|
|
|
125
125
|
const capSeconds = (options.capMinutes ?? 60) * 60;
|
|
126
126
|
const clockFn = options.clockFn ?? systemMonotonicClock;
|
|
127
127
|
const sleepFn = options.sleepFn ?? defaultSleep;
|
|
128
|
-
const callReadinessFn = options.callReadinessFn ??
|
|
128
|
+
const callReadinessFn = options.callReadinessFn ??
|
|
129
|
+
((n, r) => callReadiness(n, r, {
|
|
130
|
+
runGh: options.runGh,
|
|
131
|
+
projectRoot: options.projectRoot ?? process.cwd(),
|
|
132
|
+
}));
|
|
129
133
|
const startedAt = clockFn.now();
|
|
130
134
|
const intervalSchedule = cadenceIntervals(cadence);
|
|
131
135
|
const minCadenceSec = intervalSchedule.length > 0
|
|
@@ -27,7 +27,9 @@ export function callReadiness(prNumber, repo, options = {}) {
|
|
|
27
27
|
try {
|
|
28
28
|
process.stderr.write = captureWrite;
|
|
29
29
|
const runGh = options.runGh ?? defaultRunGh;
|
|
30
|
-
const result = computeGateResult(prNumber, repo, runGh
|
|
30
|
+
const result = computeGateResult(prNumber, repo, runGh, {
|
|
31
|
+
projectRoot: options.projectRoot ?? process.cwd(),
|
|
32
|
+
});
|
|
31
33
|
const payload = gateResultToDict(result);
|
|
32
34
|
const exitCode = exitCodeFor(result);
|
|
33
35
|
return {
|
|
@@ -17,6 +17,12 @@ export interface MonitorOptions {
|
|
|
17
17
|
readonly clockFn?: MonotonicClock;
|
|
18
18
|
readonly callReadinessFn?: CallReadinessFn;
|
|
19
19
|
readonly runGh?: RunGhFn;
|
|
20
|
+
/**
|
|
21
|
+
* Project root for plan.policy.review.minGreptileConfidence (#3095).
|
|
22
|
+
* When pr-monitor targets a remote repo from a different cwd, pass the
|
|
23
|
+
* monitored project's root so confidence policy is not resolved from cwd.
|
|
24
|
+
*/
|
|
25
|
+
readonly projectRoot?: string | null;
|
|
20
26
|
}
|
|
21
27
|
export interface MonitorRunResult {
|
|
22
28
|
readonly exitCode: number;
|
|
@@ -26,5 +32,7 @@ export interface MonitorRunResult {
|
|
|
26
32
|
export interface CallReadinessOptions {
|
|
27
33
|
readonly runGh?: RunGhFn;
|
|
28
34
|
readonly timeoutMs?: number;
|
|
35
|
+
/** Project root for minGreptileConfidence resolve (#3095). */
|
|
36
|
+
readonly projectRoot?: string | null;
|
|
29
37
|
}
|
|
30
38
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type AgentMergeEvaluateResult } from "../policy/require-human-merge.js";
|
|
2
2
|
import { type SemanticGreenFn } from "./semantic-green.js";
|
|
3
3
|
import type { MergeFn, MonitorFn, ProtectedCheckFn, WaitMergeableResult } from "./types.js";
|
|
4
|
+
/** Post-merge umbrella checklist + current-shape refresh (#1649). */
|
|
5
|
+
export type UmbrellaReconcileFn = (projectRoot: string, repo: string) => void;
|
|
4
6
|
export interface WaitMergeableOptions {
|
|
5
7
|
readonly protectedFn?: ProtectedCheckFn;
|
|
6
8
|
readonly monitorFn?: MonitorFn;
|
|
@@ -21,6 +23,12 @@ export interface WaitMergeableOptions {
|
|
|
21
23
|
readonly agentMergeFn?: (projectRoot: string) => AgentMergeEvaluateResult;
|
|
22
24
|
/** When true, skip human-merge / intent preflight (tests only). */
|
|
23
25
|
readonly skipHumanMergeGate?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Post-merge umbrella reconcile (#1649). Defaults to live reconcileUmbrellas.
|
|
28
|
+
* Pass `null` to skip (unit tests that inject mergeFn must pass null so they
|
|
29
|
+
* never mutate real GitHub current-shape comments from the worktree cwd).
|
|
30
|
+
*/
|
|
31
|
+
readonly umbrellaReconcileFn?: UmbrellaReconcileFn | null;
|
|
24
32
|
}
|
|
25
33
|
/** Run protected-check -> wait -> merge cascade (#1369). */
|
|
26
34
|
export declare function waitMergeableAndMerge(prNumber: number, repo: string, options: {
|