executable-stories-formatters 1.20.0 → 1.21.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/index.d.cts CHANGED
@@ -1534,8 +1534,10 @@ interface ReviewClaim {
1534
1534
  status: TestStatus;
1535
1535
  /** Derived from file convention / `audience:` tag. */
1536
1536
  audience: ReviewAudience;
1537
- /** Declared via `change:*` tag (defaults to `unknown`). */
1537
+ /** Declared via `change:*` tag (defaults to `unknown`), or inferred by Jev when `changeTypeConfidence` is set. */
1538
1538
  changeType: ChangeType;
1539
+ /** Present only when `changeType` was inferred rather than declared. */
1540
+ changeTypeConfidence?: number;
1539
1541
  /** Graded credibility of this claim's proof. */
1540
1542
  strength: EvidenceStrength;
1541
1543
  /** Human-readable reasons the strength was assigned (what corroborated / what was missing). */
@@ -2944,6 +2946,47 @@ declare function buildCheck(args: CheckArgs, _deps?: CheckDeps): CheckReport;
2944
2946
  */
2945
2947
  declare function renderCheck(report: CheckReport, format: "text" | "json"): string;
2946
2948
 
2949
+ type JevQuestion = {
2950
+ type: "noul";
2951
+ instructions: string;
2952
+ } | {
2953
+ type: "choice";
2954
+ instructions: string;
2955
+ criteria: Record<string, string | null>;
2956
+ } | {
2957
+ type: "score";
2958
+ instructions: string;
2959
+ criteria: string[];
2960
+ };
2961
+ type JevAnswer = {
2962
+ type: "noul";
2963
+ noul: number;
2964
+ } | {
2965
+ type: "choice";
2966
+ choice: string;
2967
+ probabilities: Record<string, number>;
2968
+ confidence: number;
2969
+ } | {
2970
+ type: "score";
2971
+ score: number;
2972
+ probabilities: Record<string, number>;
2973
+ confidence: number;
2974
+ };
2975
+ interface JevClient {
2976
+ model: string;
2977
+ ask(state: unknown, questions: Record<string, JevQuestion>): Promise<Record<string, JevAnswer>>;
2978
+ }
2979
+ interface JevClientOptions {
2980
+ apiKey: string;
2981
+ model?: string;
2982
+ endpoint?: string;
2983
+ fetch?: typeof globalThis.fetch;
2984
+ timeoutMs?: number;
2985
+ }
2986
+ declare function createJevClient(options: JevClientOptions): JevClient;
2987
+ /** A client when `JEV_API_KEY` is set, else undefined (deterministic output only). */
2988
+ declare function jevFromEnv(env?: NodeJS.ProcessEnv): JevClient | undefined;
2989
+
2947
2990
  /**
2948
2991
  * `goal` — a behavioral definition-of-done for autonomous agent loops.
2949
2992
  *
@@ -2985,6 +3028,8 @@ interface GoalReport {
2985
3028
  ratchet: {
2986
3029
  enforced: boolean;
2987
3030
  violations: RatchetViolation[];
3031
+ /** Jev's read of scenarios that changed without shrinking. Never affects `met`. */
3032
+ advisories: RatchetViolation[];
2988
3033
  };
2989
3034
  }
2990
3035
  interface GoalArgs {
@@ -2999,6 +3044,13 @@ interface GoalArgs {
2999
3044
  }
3000
3045
  type GoalDeps = Record<string, never>;
3001
3046
  declare function buildGoal(args: GoalArgs, _deps?: GoalDeps): GoalReport;
3047
+ /**
3048
+ * The step-count ratchet sees counts, so merging two steps keeps it clean.
3049
+ * When a baseline scenario's steps were rewritten without shrinking, ask Jev
3050
+ * whether the new version checks less. Advisory only: `met` is decided by
3051
+ * the rules above, and this is a judgment.
3052
+ */
3053
+ declare function enrichGoal(report: GoalReport, args: GoalArgs, jev: JevClient): Promise<GoalReport>;
3002
3054
  declare function renderGoal(report: GoalReport, format: "text" | "json"): string;
3003
3055
 
3004
3056
  /**
@@ -3043,7 +3095,18 @@ interface TriageItem {
3043
3095
  /** Passed in the baseline, failing now. Ranked first. */
3044
3096
  regressed: boolean;
3045
3097
  reason: "regression" | "failing";
3098
+ /** Jev's pick when `covers` is empty: a path the run already routes to, with its probability. */
3099
+ suggestedCovers?: {
3100
+ path: string;
3101
+ probability: number;
3102
+ };
3103
+ /** Jev's read of what failed: the product, the test itself, or the environment. */
3104
+ failureKind?: {
3105
+ kind: FailureKind;
3106
+ confidence: number;
3107
+ };
3046
3108
  }
3109
+ type FailureKind = "product" | "test" | "infra";
3047
3110
  interface TriageReport {
3048
3111
  total: number;
3049
3112
  failing: number;
@@ -3062,6 +3125,14 @@ interface TriageArgs {
3062
3125
  }
3063
3126
  type TriageDeps = Record<string, never>;
3064
3127
  declare function buildTriage(args: TriageArgs, _deps?: TriageDeps): TriageReport;
3128
+ /**
3129
+ * For each failing scenario with no `covers`, ask Jev to pick from the paths
3130
+ * this run already routes to (every declared `covers`, plus CODEOWNERS
3131
+ * patterns), and to say whether the product, the test, or the environment
3132
+ * failed. The declared-`covers` count stays as declared: a suggestion is not
3133
+ * a declaration.
3134
+ */
3135
+ declare function enrichTriage(report: TriageReport, testCases: TestCaseResult[], jev: JevClient, codeowners?: readonly CodeownersRule[]): Promise<TriageReport>;
3065
3136
  interface RenderTriageOptions {
3066
3137
  /** Group the text worklist under each CODEOWNERS owner. */
3067
3138
  byOwner?: boolean;
@@ -3249,11 +3320,12 @@ declare function gradeEvidence(testCase: TestCaseResult, audience: ReviewAudienc
3249
3320
  */
3250
3321
  declare function buildReview(run: ReviewResult["run"], context?: ReviewContext): ReviewResult;
3251
3322
  /**
3252
- * Code Diff integrity diagnostics: orphaned/ambiguous anchors and unverified
3253
- * scenario references. The CLI prints these as warnings; `--strict-code-diff`
3254
- * turns them into review-gate failures so CI catches explainers that lost
3255
- * their grounding.
3323
+ * For claims with no `change:*` tag, ask Jev to pick the change-type from the
3324
+ * scenario plus the hunks of the files it covers. Confident answers are
3325
+ * written back with their confidence so every renderer can say "inferred";
3326
+ * the rest stay `unknown`.
3256
3327
  */
3328
+ declare function enrichReview(review: ReviewResult, jev: JevClient): Promise<ReviewResult>;
3257
3329
  declare function codeDiffDiagnostics(review: ReviewResult): string[];
3258
3330
 
3259
3331
  /**
@@ -3628,4 +3700,4 @@ declare function normalizeVitestResults(testModules: Parameters<typeof adaptVite
3628
3700
  */
3629
3701
  declare function normalizePlaywrightResults(testResults: Parameters<typeof adaptPlaywrightRun>[0], adapterOptions?: Parameters<typeof adaptPlaywrightRun>[1], canonicalizeOptions?: CanonicalizeOptions): TestRunResult;
3630
3702
 
3631
- export { type AdapterDeps, AgentTextFormatter, type AggregateDeps, type AggregateResult, type AnchorResolution, type AnchorState, type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, type AttachPolicy, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, type CaseBody, type CaseResult, type ChangeType, type ChangedFile, type ChangedFileReview, type CheckArgs, type CheckDeps, type CheckFailure, type CheckReport, type CheckStep, type CodeDiffAnnotation, type CodeDiffAnnotationInput, type CodeDiffEvidence, type CodeDiffInput, type CodeDiffScenarioRef, type CodeDiffSidecar, type CodeDiffSidecarAnnotation, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, type CoverageClass, type CoverageJson, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DEFAULT_LOCKFILE_PATH, type DeploymentEntry, type DeploymentLedger, type DeploymentStatus, type DiffAnchor, type DiffHunk, type DiffLine, type DiffRunsOptions, type EnvironmentDrift, type EvidenceStrength, type ExecutableStoriesConfig, type FetchFn, type FileChangeKind, type FileDiff, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type GoalArgs, type GoalDeps, type GoalReport, type GoalRequirementResult, type HistoryEntry, type HistoryStore, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type LockEntry, type Lockfile, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, type NotificationSummary, type NotifyCondition, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, PROVIDER_NAMES, type PerformanceTrend, type ProviderName, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, type RatchetViolation, type RecordDeploymentArgs, type RecordDeploymentResult, type RecordResultsSummary, type ReleaseManifest, ReleaseManifestFormatter, type RemoteCase, ReportGenerator, type ResolvedFormatterOptions, type ResultAttachment, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffChangelogFormatter, type RunDiffChangelogOptions, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, type RunsResetResult, type RunsStatusReport, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StoryReportJsonFormatter, type StoryReportJsonOptions, type SyncAnalysis, type SyncApplyResult, type SyncEngineConfig, type SyncProvider, type SyncTargets, type TestHistory, type TestMetrics, type TestRailConfig, TraceabilityCsvFormatter, type TraceabilityMatrix, TraceabilityMatrixFormatter, type TraceabilityRequirement, type TriageArgs, type TriageDeps, type TriageItem, type TriageReport, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, type XrayConfig, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, aggregateReports, analyzeSync, applySync, assembleCodeDiff, buildCheck, buildCoverageJson, buildGoal, buildProvider, buildReview, buildTriage, bundleAssets, calculateFlakiness, calculateStability, classifyStatusChange, clearVersionCache, codeDiffDiagnostics, collectAttachments, computeTestMetrics, copyMarkdownAssets, createAnchor, createPrCommentSummary, createReportGenerator, createTestRailProvider, createXrayProvider, deriveAudience, deriveChangeType, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, emptyLockfile, findGitDir, generateRunComparison, getDeploymentStatus, getEnvironmentDrift, gradeEvidence, hasSufficientHistory, hashCaseBody, isProviderName, isReviewableSource, isTestFile, joinNameAndExt, listScenarios, loadHistory, normalizeFormats, normalizeJestResults, normalizePlaywrightResults, normalizeVitestResults, parseLockfile, parseUnifiedDiff, projectBehaviours, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readLockfile, readPackageVersion, recordDeployment, regenerateArtifacts, regenerateRun, relocateAnchor, renderApplyResult, renderCheck, renderCoverageMarkdown, renderCoverageText, renderGoal, renderPlan, renderTriage, rewriteAssetPaths, runsReset, runsStatus, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, serializeLockfile, signBody, startWatch, stripAnsi, toAgentText, toBehaviorManifest, toCaseBody, toReleaseManifest, toScenarioIndex, toTraceabilityMatrix, updateHistory, writeLockfile };
3703
+ export { type AdapterDeps, AgentTextFormatter, type AggregateDeps, type AggregateResult, type AnchorResolution, type AnchorState, type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, type AttachPolicy, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, type CaseBody, type CaseResult, type ChangeType, type ChangedFile, type ChangedFileReview, type CheckArgs, type CheckDeps, type CheckFailure, type CheckReport, type CheckStep, type CodeDiffAnnotation, type CodeDiffAnnotationInput, type CodeDiffEvidence, type CodeDiffInput, type CodeDiffScenarioRef, type CodeDiffSidecar, type CodeDiffSidecarAnnotation, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, type CoverageClass, type CoverageJson, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DEFAULT_LOCKFILE_PATH, type DeploymentEntry, type DeploymentLedger, type DeploymentStatus, type DiffAnchor, type DiffHunk, type DiffLine, type DiffRunsOptions, type EnvironmentDrift, type EvidenceStrength, type ExecutableStoriesConfig, type FailureKind, type FetchFn, type FileChangeKind, type FileDiff, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type GoalArgs, type GoalDeps, type GoalReport, type GoalRequirementResult, type HistoryEntry, type HistoryStore, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JevAnswer, type JevClient, type JevQuestion, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type LockEntry, type Lockfile, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, type NotificationSummary, type NotifyCondition, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, PROVIDER_NAMES, type PerformanceTrend, type ProviderName, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, type RatchetViolation, type RecordDeploymentArgs, type RecordDeploymentResult, type RecordResultsSummary, type ReleaseManifest, ReleaseManifestFormatter, type RemoteCase, ReportGenerator, type ResolvedFormatterOptions, type ResultAttachment, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffChangelogFormatter, type RunDiffChangelogOptions, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, type RunsResetResult, type RunsStatusReport, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StoryReportJsonFormatter, type StoryReportJsonOptions, type SyncAnalysis, type SyncApplyResult, type SyncEngineConfig, type SyncProvider, type SyncTargets, type TestHistory, type TestMetrics, type TestRailConfig, TraceabilityCsvFormatter, type TraceabilityMatrix, TraceabilityMatrixFormatter, type TraceabilityRequirement, type TriageArgs, type TriageDeps, type TriageItem, type TriageReport, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, type XrayConfig, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, aggregateReports, analyzeSync, applySync, assembleCodeDiff, buildCheck, buildCoverageJson, buildGoal, buildProvider, buildReview, buildTriage, bundleAssets, calculateFlakiness, calculateStability, classifyStatusChange, clearVersionCache, codeDiffDiagnostics, collectAttachments, computeTestMetrics, copyMarkdownAssets, createAnchor, createJevClient, createPrCommentSummary, createReportGenerator, createTestRailProvider, createXrayProvider, deriveAudience, deriveChangeType, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, emptyLockfile, enrichGoal, enrichReview, enrichTriage, findGitDir, generateRunComparison, getDeploymentStatus, getEnvironmentDrift, gradeEvidence, hasSufficientHistory, hashCaseBody, isProviderName, isReviewableSource, isTestFile, jevFromEnv, joinNameAndExt, listScenarios, loadHistory, normalizeFormats, normalizeJestResults, normalizePlaywrightResults, normalizeVitestResults, parseLockfile, parseUnifiedDiff, projectBehaviours, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readLockfile, readPackageVersion, recordDeployment, regenerateArtifacts, regenerateRun, relocateAnchor, renderApplyResult, renderCheck, renderCoverageMarkdown, renderCoverageText, renderGoal, renderPlan, renderTriage, rewriteAssetPaths, runsReset, runsStatus, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, serializeLockfile, signBody, startWatch, stripAnsi, toAgentText, toBehaviorManifest, toCaseBody, toReleaseManifest, toScenarioIndex, toTraceabilityMatrix, updateHistory, writeLockfile };
package/dist/index.d.ts CHANGED
@@ -1534,8 +1534,10 @@ interface ReviewClaim {
1534
1534
  status: TestStatus;
1535
1535
  /** Derived from file convention / `audience:` tag. */
1536
1536
  audience: ReviewAudience;
1537
- /** Declared via `change:*` tag (defaults to `unknown`). */
1537
+ /** Declared via `change:*` tag (defaults to `unknown`), or inferred by Jev when `changeTypeConfidence` is set. */
1538
1538
  changeType: ChangeType;
1539
+ /** Present only when `changeType` was inferred rather than declared. */
1540
+ changeTypeConfidence?: number;
1539
1541
  /** Graded credibility of this claim's proof. */
1540
1542
  strength: EvidenceStrength;
1541
1543
  /** Human-readable reasons the strength was assigned (what corroborated / what was missing). */
@@ -2944,6 +2946,47 @@ declare function buildCheck(args: CheckArgs, _deps?: CheckDeps): CheckReport;
2944
2946
  */
2945
2947
  declare function renderCheck(report: CheckReport, format: "text" | "json"): string;
2946
2948
 
2949
+ type JevQuestion = {
2950
+ type: "noul";
2951
+ instructions: string;
2952
+ } | {
2953
+ type: "choice";
2954
+ instructions: string;
2955
+ criteria: Record<string, string | null>;
2956
+ } | {
2957
+ type: "score";
2958
+ instructions: string;
2959
+ criteria: string[];
2960
+ };
2961
+ type JevAnswer = {
2962
+ type: "noul";
2963
+ noul: number;
2964
+ } | {
2965
+ type: "choice";
2966
+ choice: string;
2967
+ probabilities: Record<string, number>;
2968
+ confidence: number;
2969
+ } | {
2970
+ type: "score";
2971
+ score: number;
2972
+ probabilities: Record<string, number>;
2973
+ confidence: number;
2974
+ };
2975
+ interface JevClient {
2976
+ model: string;
2977
+ ask(state: unknown, questions: Record<string, JevQuestion>): Promise<Record<string, JevAnswer>>;
2978
+ }
2979
+ interface JevClientOptions {
2980
+ apiKey: string;
2981
+ model?: string;
2982
+ endpoint?: string;
2983
+ fetch?: typeof globalThis.fetch;
2984
+ timeoutMs?: number;
2985
+ }
2986
+ declare function createJevClient(options: JevClientOptions): JevClient;
2987
+ /** A client when `JEV_API_KEY` is set, else undefined (deterministic output only). */
2988
+ declare function jevFromEnv(env?: NodeJS.ProcessEnv): JevClient | undefined;
2989
+
2947
2990
  /**
2948
2991
  * `goal` — a behavioral definition-of-done for autonomous agent loops.
2949
2992
  *
@@ -2985,6 +3028,8 @@ interface GoalReport {
2985
3028
  ratchet: {
2986
3029
  enforced: boolean;
2987
3030
  violations: RatchetViolation[];
3031
+ /** Jev's read of scenarios that changed without shrinking. Never affects `met`. */
3032
+ advisories: RatchetViolation[];
2988
3033
  };
2989
3034
  }
2990
3035
  interface GoalArgs {
@@ -2999,6 +3044,13 @@ interface GoalArgs {
2999
3044
  }
3000
3045
  type GoalDeps = Record<string, never>;
3001
3046
  declare function buildGoal(args: GoalArgs, _deps?: GoalDeps): GoalReport;
3047
+ /**
3048
+ * The step-count ratchet sees counts, so merging two steps keeps it clean.
3049
+ * When a baseline scenario's steps were rewritten without shrinking, ask Jev
3050
+ * whether the new version checks less. Advisory only: `met` is decided by
3051
+ * the rules above, and this is a judgment.
3052
+ */
3053
+ declare function enrichGoal(report: GoalReport, args: GoalArgs, jev: JevClient): Promise<GoalReport>;
3002
3054
  declare function renderGoal(report: GoalReport, format: "text" | "json"): string;
3003
3055
 
3004
3056
  /**
@@ -3043,7 +3095,18 @@ interface TriageItem {
3043
3095
  /** Passed in the baseline, failing now. Ranked first. */
3044
3096
  regressed: boolean;
3045
3097
  reason: "regression" | "failing";
3098
+ /** Jev's pick when `covers` is empty: a path the run already routes to, with its probability. */
3099
+ suggestedCovers?: {
3100
+ path: string;
3101
+ probability: number;
3102
+ };
3103
+ /** Jev's read of what failed: the product, the test itself, or the environment. */
3104
+ failureKind?: {
3105
+ kind: FailureKind;
3106
+ confidence: number;
3107
+ };
3046
3108
  }
3109
+ type FailureKind = "product" | "test" | "infra";
3047
3110
  interface TriageReport {
3048
3111
  total: number;
3049
3112
  failing: number;
@@ -3062,6 +3125,14 @@ interface TriageArgs {
3062
3125
  }
3063
3126
  type TriageDeps = Record<string, never>;
3064
3127
  declare function buildTriage(args: TriageArgs, _deps?: TriageDeps): TriageReport;
3128
+ /**
3129
+ * For each failing scenario with no `covers`, ask Jev to pick from the paths
3130
+ * this run already routes to (every declared `covers`, plus CODEOWNERS
3131
+ * patterns), and to say whether the product, the test, or the environment
3132
+ * failed. The declared-`covers` count stays as declared: a suggestion is not
3133
+ * a declaration.
3134
+ */
3135
+ declare function enrichTriage(report: TriageReport, testCases: TestCaseResult[], jev: JevClient, codeowners?: readonly CodeownersRule[]): Promise<TriageReport>;
3065
3136
  interface RenderTriageOptions {
3066
3137
  /** Group the text worklist under each CODEOWNERS owner. */
3067
3138
  byOwner?: boolean;
@@ -3249,11 +3320,12 @@ declare function gradeEvidence(testCase: TestCaseResult, audience: ReviewAudienc
3249
3320
  */
3250
3321
  declare function buildReview(run: ReviewResult["run"], context?: ReviewContext): ReviewResult;
3251
3322
  /**
3252
- * Code Diff integrity diagnostics: orphaned/ambiguous anchors and unverified
3253
- * scenario references. The CLI prints these as warnings; `--strict-code-diff`
3254
- * turns them into review-gate failures so CI catches explainers that lost
3255
- * their grounding.
3323
+ * For claims with no `change:*` tag, ask Jev to pick the change-type from the
3324
+ * scenario plus the hunks of the files it covers. Confident answers are
3325
+ * written back with their confidence so every renderer can say "inferred";
3326
+ * the rest stay `unknown`.
3256
3327
  */
3328
+ declare function enrichReview(review: ReviewResult, jev: JevClient): Promise<ReviewResult>;
3257
3329
  declare function codeDiffDiagnostics(review: ReviewResult): string[];
3258
3330
 
3259
3331
  /**
@@ -3628,4 +3700,4 @@ declare function normalizeVitestResults(testModules: Parameters<typeof adaptVite
3628
3700
  */
3629
3701
  declare function normalizePlaywrightResults(testResults: Parameters<typeof adaptPlaywrightRun>[0], adapterOptions?: Parameters<typeof adaptPlaywrightRun>[1], canonicalizeOptions?: CanonicalizeOptions): TestRunResult;
3630
3702
 
3631
- export { type AdapterDeps, AgentTextFormatter, type AggregateDeps, type AggregateResult, type AnchorResolution, type AnchorState, type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, type AttachPolicy, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, type CaseBody, type CaseResult, type ChangeType, type ChangedFile, type ChangedFileReview, type CheckArgs, type CheckDeps, type CheckFailure, type CheckReport, type CheckStep, type CodeDiffAnnotation, type CodeDiffAnnotationInput, type CodeDiffEvidence, type CodeDiffInput, type CodeDiffScenarioRef, type CodeDiffSidecar, type CodeDiffSidecarAnnotation, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, type CoverageClass, type CoverageJson, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DEFAULT_LOCKFILE_PATH, type DeploymentEntry, type DeploymentLedger, type DeploymentStatus, type DiffAnchor, type DiffHunk, type DiffLine, type DiffRunsOptions, type EnvironmentDrift, type EvidenceStrength, type ExecutableStoriesConfig, type FetchFn, type FileChangeKind, type FileDiff, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type GoalArgs, type GoalDeps, type GoalReport, type GoalRequirementResult, type HistoryEntry, type HistoryStore, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type LockEntry, type Lockfile, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, type NotificationSummary, type NotifyCondition, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, PROVIDER_NAMES, type PerformanceTrend, type ProviderName, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, type RatchetViolation, type RecordDeploymentArgs, type RecordDeploymentResult, type RecordResultsSummary, type ReleaseManifest, ReleaseManifestFormatter, type RemoteCase, ReportGenerator, type ResolvedFormatterOptions, type ResultAttachment, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffChangelogFormatter, type RunDiffChangelogOptions, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, type RunsResetResult, type RunsStatusReport, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StoryReportJsonFormatter, type StoryReportJsonOptions, type SyncAnalysis, type SyncApplyResult, type SyncEngineConfig, type SyncProvider, type SyncTargets, type TestHistory, type TestMetrics, type TestRailConfig, TraceabilityCsvFormatter, type TraceabilityMatrix, TraceabilityMatrixFormatter, type TraceabilityRequirement, type TriageArgs, type TriageDeps, type TriageItem, type TriageReport, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, type XrayConfig, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, aggregateReports, analyzeSync, applySync, assembleCodeDiff, buildCheck, buildCoverageJson, buildGoal, buildProvider, buildReview, buildTriage, bundleAssets, calculateFlakiness, calculateStability, classifyStatusChange, clearVersionCache, codeDiffDiagnostics, collectAttachments, computeTestMetrics, copyMarkdownAssets, createAnchor, createPrCommentSummary, createReportGenerator, createTestRailProvider, createXrayProvider, deriveAudience, deriveChangeType, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, emptyLockfile, findGitDir, generateRunComparison, getDeploymentStatus, getEnvironmentDrift, gradeEvidence, hasSufficientHistory, hashCaseBody, isProviderName, isReviewableSource, isTestFile, joinNameAndExt, listScenarios, loadHistory, normalizeFormats, normalizeJestResults, normalizePlaywrightResults, normalizeVitestResults, parseLockfile, parseUnifiedDiff, projectBehaviours, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readLockfile, readPackageVersion, recordDeployment, regenerateArtifacts, regenerateRun, relocateAnchor, renderApplyResult, renderCheck, renderCoverageMarkdown, renderCoverageText, renderGoal, renderPlan, renderTriage, rewriteAssetPaths, runsReset, runsStatus, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, serializeLockfile, signBody, startWatch, stripAnsi, toAgentText, toBehaviorManifest, toCaseBody, toReleaseManifest, toScenarioIndex, toTraceabilityMatrix, updateHistory, writeLockfile };
3703
+ export { type AdapterDeps, AgentTextFormatter, type AggregateDeps, type AggregateResult, type AnchorResolution, type AnchorState, type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, type AttachPolicy, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, type CaseBody, type CaseResult, type ChangeType, type ChangedFile, type ChangedFileReview, type CheckArgs, type CheckDeps, type CheckFailure, type CheckReport, type CheckStep, type CodeDiffAnnotation, type CodeDiffAnnotationInput, type CodeDiffEvidence, type CodeDiffInput, type CodeDiffScenarioRef, type CodeDiffSidecar, type CodeDiffSidecarAnnotation, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, type CoverageClass, type CoverageJson, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DEFAULT_LOCKFILE_PATH, type DeploymentEntry, type DeploymentLedger, type DeploymentStatus, type DiffAnchor, type DiffHunk, type DiffLine, type DiffRunsOptions, type EnvironmentDrift, type EvidenceStrength, type ExecutableStoriesConfig, type FailureKind, type FetchFn, type FileChangeKind, type FileDiff, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type GoalArgs, type GoalDeps, type GoalReport, type GoalRequirementResult, type HistoryEntry, type HistoryStore, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JevAnswer, type JevClient, type JevQuestion, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type LockEntry, type Lockfile, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, type NotificationSummary, type NotifyCondition, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, PROVIDER_NAMES, type PerformanceTrend, type ProviderName, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, type RatchetViolation, type RecordDeploymentArgs, type RecordDeploymentResult, type RecordResultsSummary, type ReleaseManifest, ReleaseManifestFormatter, type RemoteCase, ReportGenerator, type ResolvedFormatterOptions, type ResultAttachment, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffChangelogFormatter, type RunDiffChangelogOptions, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, type RunsResetResult, type RunsStatusReport, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StoryReportJsonFormatter, type StoryReportJsonOptions, type SyncAnalysis, type SyncApplyResult, type SyncEngineConfig, type SyncProvider, type SyncTargets, type TestHistory, type TestMetrics, type TestRailConfig, TraceabilityCsvFormatter, type TraceabilityMatrix, TraceabilityMatrixFormatter, type TraceabilityRequirement, type TriageArgs, type TriageDeps, type TriageItem, type TriageReport, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, type XrayConfig, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, aggregateReports, analyzeSync, applySync, assembleCodeDiff, buildCheck, buildCoverageJson, buildGoal, buildProvider, buildReview, buildTriage, bundleAssets, calculateFlakiness, calculateStability, classifyStatusChange, clearVersionCache, codeDiffDiagnostics, collectAttachments, computeTestMetrics, copyMarkdownAssets, createAnchor, createJevClient, createPrCommentSummary, createReportGenerator, createTestRailProvider, createXrayProvider, deriveAudience, deriveChangeType, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, emptyLockfile, enrichGoal, enrichReview, enrichTriage, findGitDir, generateRunComparison, getDeploymentStatus, getEnvironmentDrift, gradeEvidence, hasSufficientHistory, hashCaseBody, isProviderName, isReviewableSource, isTestFile, jevFromEnv, joinNameAndExt, listScenarios, loadHistory, normalizeFormats, normalizeJestResults, normalizePlaywrightResults, normalizeVitestResults, parseLockfile, parseUnifiedDiff, projectBehaviours, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readLockfile, readPackageVersion, recordDeployment, regenerateArtifacts, regenerateRun, relocateAnchor, renderApplyResult, renderCheck, renderCoverageMarkdown, renderCoverageText, renderGoal, renderPlan, renderTriage, rewriteAssetPaths, runsReset, runsStatus, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, serializeLockfile, signBody, startWatch, stripAnsi, toAgentText, toBehaviorManifest, toCaseBody, toReleaseManifest, toScenarioIndex, toTraceabilityMatrix, updateHistory, writeLockfile };
package/dist/index.js CHANGED
@@ -4991,6 +4991,50 @@ function sourceBaseKey(sourceFile) {
4991
4991
  return dot > slash ? sourceFile.slice(0, dot) : sourceFile;
4992
4992
  }
4993
4993
 
4994
+ // src/jev.ts
4995
+ var JEV_ENDPOINT = "https://api.typesafe.ai/v1/systemone";
4996
+ var JEV_MODEL = "jev-latest";
4997
+ function createJevClient(options) {
4998
+ const {
4999
+ apiKey,
5000
+ model = JEV_MODEL,
5001
+ endpoint = JEV_ENDPOINT,
5002
+ fetch = globalThis.fetch,
5003
+ timeoutMs = 1e4
5004
+ } = options;
5005
+ return {
5006
+ model,
5007
+ // One attempt per question set; add backoff on 429/529 if a loop hits rate limits.
5008
+ async ask(state, questions) {
5009
+ const response = await fetch(endpoint, {
5010
+ method: "POST",
5011
+ headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
5012
+ body: JSON.stringify({ model, state, questions }),
5013
+ signal: AbortSignal.timeout(timeoutMs)
5014
+ });
5015
+ if (!response.ok) throw new Error(`Jev ${response.status}: ${(await response.text()).slice(0, 200)}`);
5016
+ const body = await response.json();
5017
+ if (!body.answers) throw new Error("Jev response has no answers");
5018
+ return body.answers;
5019
+ }
5020
+ };
5021
+ }
5022
+ function jevFromEnv(env = process.env) {
5023
+ const apiKey = env.JEV_API_KEY;
5024
+ if (!apiKey) return void 0;
5025
+ return createJevClient({
5026
+ apiKey,
5027
+ ...env.JEV_MODEL ? { model: env.JEV_MODEL } : {},
5028
+ ...env.JEV_ENDPOINT ? { endpoint: env.JEV_ENDPOINT } : {}
5029
+ });
5030
+ }
5031
+ function asChoice(answer) {
5032
+ return answer?.type === "choice" ? answer : void 0;
5033
+ }
5034
+ function asNoul(answer) {
5035
+ return answer?.type === "noul" ? answer.noul : void 0;
5036
+ }
5037
+
4994
5038
  // src/review/build-review.ts
4995
5039
  var STRENGTH_RANK = {
4996
5040
  none: 0,
@@ -5191,6 +5235,61 @@ function buildReview(run, context = { changedFiles: [] }) {
5191
5235
  codeDiffs: (context.codeDiffs ?? []).map((d) => buildCodeDiff(d, run, context))
5192
5236
  };
5193
5237
  }
5238
+ var REVIEW_CHANGE_TYPE_MIN_CONFIDENCE = 0.6;
5239
+ var PATCH_EXCERPT_CHARS = 4e3;
5240
+ var CHANGE_TYPE_CRITERIA = {
5241
+ feature: "new user-visible behaviour or capability",
5242
+ bugfix: "corrects behaviour that was wrong",
5243
+ refactor: "restructures code without changing behaviour",
5244
+ perf: "same behaviour, faster or cheaper",
5245
+ deps: "dependency, toolchain, or lockfile change"
5246
+ };
5247
+ async function enrichReview(review, jev) {
5248
+ const untagged = review.claims.filter((c) => c.changeType === "unknown" && c.coversFiles.length > 0);
5249
+ if (untagged.length === 0) return review;
5250
+ const hunksByPath = /* @__PURE__ */ new Map();
5251
+ for (const group of review.context.codeDiffs ?? []) {
5252
+ for (const file of parseUnifiedDiff(group.patch)) {
5253
+ const path15 = file.newPath ?? file.oldPath;
5254
+ if (!path15) continue;
5255
+ const text2 = file.hunks.flatMap((h) => h.lines.map((l) => (l.kind === "add" ? "+" : l.kind === "del" ? "-" : " ") + l.text));
5256
+ hunksByPath.set(path15, [...hunksByPath.get(path15) ?? [], ...text2]);
5257
+ }
5258
+ }
5259
+ const inferred = /* @__PURE__ */ new Map();
5260
+ await Promise.all(
5261
+ untagged.map(async (claim) => {
5262
+ const patch = claim.coversFiles.flatMap((f) => hunksByPath.get(f) ?? []).join("\n").slice(0, PATCH_EXCERPT_CHARS);
5263
+ const answers = await jev.ask(
5264
+ {
5265
+ scenario: claim.scenario,
5266
+ steps: claim.testCase.story.steps.map((s) => `${s.keyword} ${s.text}`),
5267
+ ...claim.intent ? { intent: claim.intent } : {},
5268
+ changedFiles: claim.coversFiles,
5269
+ ...patch ? { patch } : {}
5270
+ },
5271
+ {
5272
+ changeType: {
5273
+ type: "choice",
5274
+ instructions: "What kind of change does this scenario prove?",
5275
+ criteria: CHANGE_TYPE_CRITERIA
5276
+ }
5277
+ }
5278
+ );
5279
+ const answer = asChoice(answers.changeType);
5280
+ if (!answer || answer.confidence < REVIEW_CHANGE_TYPE_MIN_CONFIDENCE) return;
5281
+ const changeType = answer.choice;
5282
+ if (VALID_CHANGE_TYPES.has(changeType)) inferred.set(claim.id, { changeType, confidence: answer.confidence });
5283
+ })
5284
+ );
5285
+ return {
5286
+ ...review,
5287
+ claims: review.claims.map((claim) => {
5288
+ const hit = inferred.get(claim.id);
5289
+ return hit ? { ...claim, changeType: hit.changeType, changeTypeConfidence: hit.confidence } : claim;
5290
+ })
5291
+ };
5292
+ }
5194
5293
  function codeDiffDiagnostics(review) {
5195
5294
  const issues = [];
5196
5295
  for (const evidence of review.codeDiffs) {
@@ -9527,9 +9626,41 @@ function buildGoal(args, _deps = {}) {
9527
9626
  requirements,
9528
9627
  regressions,
9529
9628
  regressionsEnforced: Boolean(baseline && args.enforceNoRegressions),
9530
- ratchet: { enforced: Boolean(baseline && args.enforceRatchet), violations }
9629
+ ratchet: { enforced: Boolean(baseline && args.enforceRatchet), violations, advisories: [] }
9531
9630
  };
9532
9631
  }
9632
+ var GOAL_WEAKENED_MIN_PROBABILITY = 0.75;
9633
+ var stepText = (tc) => tc.story.steps.map((s) => `${s.keyword} ${s.text}`);
9634
+ async function enrichGoal(report, args, jev) {
9635
+ const { baseline } = args;
9636
+ if (!baseline || !report.ratchet.enforced) return report;
9637
+ const current = new Map(args.run.testCases.map((tc) => [tc.id, tc]));
9638
+ const flagged = new Set(report.ratchet.violations.map((v) => v.id));
9639
+ const rewritten = baseline.testCases.flatMap((base) => {
9640
+ const now = current.get(base.id);
9641
+ if (!now || flagged.has(base.id)) return [];
9642
+ const before = stepText(base);
9643
+ const after = stepText(now);
9644
+ return before.join("\n") === after.join("\n") ? [] : [{ base, before, after }];
9645
+ });
9646
+ const advisories = (await Promise.all(
9647
+ rewritten.map(async ({ base, before, after }) => {
9648
+ const answers = await jev.ask(
9649
+ { baseline: before, now: after },
9650
+ {
9651
+ weakened: {
9652
+ type: "noul",
9653
+ instructions: "Does the NOW scenario check less than the BASELINE scenario: fewer or weaker assertions, looser expectations, or a removed check?"
9654
+ }
9655
+ }
9656
+ );
9657
+ const p = asNoul(answers.weakened);
9658
+ if (p === void 0 || p < GOAL_WEAKENED_MIN_PROBABILITY) return [];
9659
+ return [{ id: base.id, title: base.story.scenario, kind: "weakened", detail: `jev ${p.toFixed(2)}: steps rewritten, checks less` }];
9660
+ })
9661
+ )).flat();
9662
+ return { ...report, ratchet: { ...report.ratchet, advisories } };
9663
+ }
9533
9664
  function evaluate(selector, matched) {
9534
9665
  const passed = matched.filter((tc) => tc.status === "passed").length;
9535
9666
  const failing = matched.filter((tc) => tc.status !== "passed").map((tc) => tc.story.scenario);
@@ -9571,6 +9702,9 @@ function renderGoal(report, format) {
9571
9702
  lines.push(` ${v.kind}: ${v.title} (${v.detail})`);
9572
9703
  }
9573
9704
  }
9705
+ for (const v of report.ratchet.advisories) {
9706
+ lines.push(` advisory ${v.kind}: ${v.title} (${v.detail})`);
9707
+ }
9574
9708
  }
9575
9709
  return lines.join("\n");
9576
9710
  }
@@ -9640,6 +9774,55 @@ function buildTriage(args, _deps = {}) {
9640
9774
  items
9641
9775
  };
9642
9776
  }
9777
+ var TRIAGE_SUGGEST_MIN_PROBABILITY = 0.5;
9778
+ var FAILURE_KIND_CRITERIA = {
9779
+ product: "the application code under test behaves wrongly",
9780
+ test: "the scenario, assertion, fixture, or test data is wrong or stale",
9781
+ infra: "environment, network, timeout, resource, or flaky-timing failure"
9782
+ };
9783
+ async function enrichTriage(report, testCases, jev, codeowners) {
9784
+ const candidates = new Set(testCases.flatMap((tc) => tc.story.covers ?? []));
9785
+ for (const rule of codeowners ?? []) candidates.add(rule.pattern);
9786
+ const criteria = Object.fromEntries([...candidates].map((path15) => [path15, null]));
9787
+ const byId = new Map(testCases.map((tc) => [tc.id, tc]));
9788
+ const items = await Promise.all(
9789
+ report.items.map(async (item) => {
9790
+ if (item.covers.length > 0) return item;
9791
+ const tc = byId.get(item.id);
9792
+ const answers = await jev.ask(
9793
+ {
9794
+ scenario: item.scenario,
9795
+ steps: tc?.story.steps.map((s) => `${s.keyword} ${s.text}`) ?? [],
9796
+ testFile: item.location,
9797
+ error: item.errorMessage ?? null
9798
+ },
9799
+ {
9800
+ kind: {
9801
+ type: "choice",
9802
+ instructions: "What is most likely broken, given this failing scenario and its error?",
9803
+ criteria: FAILURE_KIND_CRITERIA
9804
+ },
9805
+ ...candidates.size > 0 ? {
9806
+ covers: {
9807
+ type: "choice",
9808
+ instructions: "Which of these product paths does the fix for this failure most likely land in?",
9809
+ criteria
9810
+ }
9811
+ } : {}
9812
+ }
9813
+ );
9814
+ const kind = asChoice(answers.kind);
9815
+ const covers = asChoice(answers.covers);
9816
+ const probability = covers ? covers.probabilities[covers.choice] ?? 0 : 0;
9817
+ return {
9818
+ ...item,
9819
+ ...kind && kind.choice in FAILURE_KIND_CRITERIA ? { failureKind: { kind: kind.choice, confidence: kind.confidence } } : {},
9820
+ ...covers && probability >= TRIAGE_SUGGEST_MIN_PROBABILITY ? { suggestedCovers: { path: covers.choice, probability } } : {}
9821
+ };
9822
+ })
9823
+ );
9824
+ return { ...report, items };
9825
+ }
9643
9826
  function renderTriage(report, format, options = {}) {
9644
9827
  if (format === "json") return JSON.stringify(report, null, 2);
9645
9828
  if (report.items.length === 0) {
@@ -9657,9 +9840,14 @@ function renderTriage(report, format, options = {}) {
9657
9840
  }
9658
9841
  if (item.covers.length > 0) {
9659
9842
  lines.push(` fix: ${item.covers.join(", ")}`);
9843
+ } else if (item.suggestedCovers) {
9844
+ lines.push(` fix: ${item.suggestedCovers.path}? (jev ${item.suggestedCovers.probability.toFixed(2)}, no covers declared)`);
9660
9845
  } else {
9661
9846
  lines.push(" fix: (no covers declared \u2014 add `covers` to route this to code)");
9662
9847
  }
9848
+ if (item.failureKind) {
9849
+ lines.push(` kind: ${item.failureKind.kind} (jev ${item.failureKind.confidence.toFixed(2)})`);
9850
+ }
9663
9851
  if (item.tickets.length > 0) {
9664
9852
  lines.push(` ticket: ${item.tickets.join(", ")}`);
9665
9853
  }
@@ -9910,7 +10098,8 @@ function renderClaim(lines, claim) {
9910
10098
  lines.push("");
9911
10099
  lines.push(`- File: \`${claim.sourceFile}:${claim.sourceLine}\``);
9912
10100
  if (claim.changeType !== "unknown") {
9913
- lines.push(`- Change: \`${claim.changeType}\``);
10101
+ const inferred = claim.changeTypeConfidence === void 0 ? "" : ` _(inferred, jev ${claim.changeTypeConfidence.toFixed(2)})_`;
10102
+ lines.push(`- Change: \`${claim.changeType}\`${inferred}`);
9914
10103
  }
9915
10104
  const tickets = claim.testCase.story.tickets ?? [];
9916
10105
  if (tickets.length > 0) {
@@ -10631,6 +10820,7 @@ export {
10631
10820
  computeTestMetrics,
10632
10821
  copyMarkdownAssets,
10633
10822
  createAnchor,
10823
+ createJevClient,
10634
10824
  createPrCommentSummary,
10635
10825
  createReportGenerator,
10636
10826
  createTestRailProvider,
@@ -10643,6 +10833,9 @@ export {
10643
10833
  diffRuns,
10644
10834
  diffStoryReports,
10645
10835
  emptyLockfile,
10836
+ enrichGoal,
10837
+ enrichReview,
10838
+ enrichTriage,
10646
10839
  findGitDir,
10647
10840
  formatDuration5 as formatDuration,
10648
10841
  generateRunComparison,
@@ -10657,6 +10850,7 @@ export {
10657
10850
  isProviderName,
10658
10851
  isReviewableSource,
10659
10852
  isTestFile,
10853
+ jevFromEnv,
10660
10854
  joinNameAndExt,
10661
10855
  listScenarios,
10662
10856
  loadHistory,