@harness-engineering/intelligence 0.1.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/LICENSE +21 -0
- package/README.md +441 -0
- package/dist/index.d.mts +901 -0
- package/dist/index.d.ts +901 -0
- package/dist/index.js +1588 -0
- package/dist/index.mjs +1520 -0
- package/package.json +62 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,901 @@
|
|
|
1
|
+
import * as _harness_engineering_types from '@harness-engineering/types';
|
|
2
|
+
import { Issue, ConcernSignal, ScopeTier, EscalationConfig } from '@harness-engineering/types';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { GraphStore } from '@harness-engineering/graph';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Raw work item — generic input from any adapter (roadmap, JIRA, GitHub, etc.)
|
|
8
|
+
*/
|
|
9
|
+
interface RawWorkItem {
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
description: string | null;
|
|
13
|
+
labels: string[];
|
|
14
|
+
metadata: Record<string, unknown>;
|
|
15
|
+
linkedItems: string[];
|
|
16
|
+
comments: string[];
|
|
17
|
+
source: 'roadmap' | 'jira' | 'github' | 'linear' | 'manual';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A system identified by SEL as affected, validated against the knowledge graph.
|
|
21
|
+
*/
|
|
22
|
+
interface AffectedSystem {
|
|
23
|
+
/** Human name from LLM output */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Graph node ID if found, null if not in graph */
|
|
26
|
+
graphNodeId: string | null;
|
|
27
|
+
/** Confidence of graph match (0 if not found) */
|
|
28
|
+
confidence: number;
|
|
29
|
+
/** Transitive dependency IDs from CascadeSimulator */
|
|
30
|
+
transitiveDeps: string[];
|
|
31
|
+
/** Number of test files covering this system */
|
|
32
|
+
testCoverage: number;
|
|
33
|
+
/** Owning team or individual, if known */
|
|
34
|
+
owner: string | null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Enriched spec — output of the Spec Enrichment Layer (SEL).
|
|
38
|
+
*/
|
|
39
|
+
interface EnrichedSpec {
|
|
40
|
+
id: string;
|
|
41
|
+
title: string;
|
|
42
|
+
intent: string;
|
|
43
|
+
summary: string;
|
|
44
|
+
affectedSystems: AffectedSystem[];
|
|
45
|
+
functionalRequirements: string[];
|
|
46
|
+
nonFunctionalRequirements: string[];
|
|
47
|
+
apiChanges: string[];
|
|
48
|
+
dbChanges: string[];
|
|
49
|
+
integrationPoints: string[];
|
|
50
|
+
assumptions: string[];
|
|
51
|
+
unknowns: string[];
|
|
52
|
+
ambiguities: string[];
|
|
53
|
+
riskSignals: string[];
|
|
54
|
+
initialComplexityHints: {
|
|
55
|
+
textualComplexity: number;
|
|
56
|
+
structuralComplexity: number;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Blast radius estimate from CML.
|
|
61
|
+
*/
|
|
62
|
+
interface BlastRadius {
|
|
63
|
+
services: number;
|
|
64
|
+
modules: number;
|
|
65
|
+
filesEstimated: number;
|
|
66
|
+
testFilesAffected: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Complexity score — output of the Complexity Modeling Layer (CML).
|
|
70
|
+
*/
|
|
71
|
+
interface ComplexityScore {
|
|
72
|
+
overall: number;
|
|
73
|
+
confidence: number;
|
|
74
|
+
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
|
75
|
+
blastRadius: BlastRadius;
|
|
76
|
+
dimensions: {
|
|
77
|
+
structural: number;
|
|
78
|
+
semantic: number;
|
|
79
|
+
historical: number;
|
|
80
|
+
};
|
|
81
|
+
reasoning: string[];
|
|
82
|
+
recommendedRoute: 'local' | 'human' | 'simulation-required';
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Simulation result — output of the Pre-Execution Simulation Layer (PESL).
|
|
86
|
+
*/
|
|
87
|
+
interface SimulationResult {
|
|
88
|
+
simulatedPlan: string[];
|
|
89
|
+
predictedFailures: string[];
|
|
90
|
+
riskHotspots: string[];
|
|
91
|
+
missingSteps: string[];
|
|
92
|
+
testGaps: string[];
|
|
93
|
+
executionConfidence: number;
|
|
94
|
+
recommendedChanges: string[];
|
|
95
|
+
abort: boolean;
|
|
96
|
+
tier: 'graph-only' | 'full-simulation';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Convert an orchestrator Issue into a generic RawWorkItem for the intelligence pipeline.
|
|
101
|
+
*/
|
|
102
|
+
declare function toRawWorkItem(issue: Issue): RawWorkItem;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* JIRA issue link reference.
|
|
106
|
+
*/
|
|
107
|
+
interface JiraIssueLink {
|
|
108
|
+
type: {
|
|
109
|
+
name: string;
|
|
110
|
+
};
|
|
111
|
+
inwardIssue?: {
|
|
112
|
+
id: string;
|
|
113
|
+
key: string;
|
|
114
|
+
};
|
|
115
|
+
outwardIssue?: {
|
|
116
|
+
id: string;
|
|
117
|
+
key: string;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* JIRA comment entry.
|
|
122
|
+
*/
|
|
123
|
+
interface JiraComment {
|
|
124
|
+
body: string;
|
|
125
|
+
author: {
|
|
126
|
+
displayName: string;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Minimal JIRA issue shape accepted by the adapter.
|
|
131
|
+
* Represents pre-fetched data from the JIRA REST API.
|
|
132
|
+
*/
|
|
133
|
+
interface JiraIssue {
|
|
134
|
+
id: string;
|
|
135
|
+
key: string;
|
|
136
|
+
fields: {
|
|
137
|
+
summary: string;
|
|
138
|
+
description: string | null;
|
|
139
|
+
labels: string[];
|
|
140
|
+
priority: {
|
|
141
|
+
id: string;
|
|
142
|
+
name: string;
|
|
143
|
+
} | null;
|
|
144
|
+
status: {
|
|
145
|
+
id: string;
|
|
146
|
+
name: string;
|
|
147
|
+
};
|
|
148
|
+
issuetype: {
|
|
149
|
+
id: string;
|
|
150
|
+
name: string;
|
|
151
|
+
};
|
|
152
|
+
created: string;
|
|
153
|
+
updated: string;
|
|
154
|
+
issuelinks: JiraIssueLink[];
|
|
155
|
+
comment: {
|
|
156
|
+
comments: JiraComment[];
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Convert a pre-fetched JIRA issue into a generic RawWorkItem.
|
|
162
|
+
*/
|
|
163
|
+
declare function jiraToRawWorkItem(issue: JiraIssue): RawWorkItem;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* GitHub label shape.
|
|
167
|
+
*/
|
|
168
|
+
interface GitHubLabel {
|
|
169
|
+
id: number;
|
|
170
|
+
name: string;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* GitHub comment shape.
|
|
174
|
+
*/
|
|
175
|
+
interface GitHubComment {
|
|
176
|
+
body: string;
|
|
177
|
+
user: {
|
|
178
|
+
login: string;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Minimal GitHub issue/PR shape accepted by the adapter.
|
|
183
|
+
* Represents pre-fetched data from the GitHub REST or GraphQL API.
|
|
184
|
+
*/
|
|
185
|
+
interface GitHubIssue {
|
|
186
|
+
id: number;
|
|
187
|
+
number: number;
|
|
188
|
+
title: string;
|
|
189
|
+
body: string | null;
|
|
190
|
+
labels: GitHubLabel[];
|
|
191
|
+
state: string;
|
|
192
|
+
html_url: string;
|
|
193
|
+
created_at: string;
|
|
194
|
+
updated_at: string;
|
|
195
|
+
pull_request: {
|
|
196
|
+
url: string;
|
|
197
|
+
} | null;
|
|
198
|
+
milestone: {
|
|
199
|
+
id: number;
|
|
200
|
+
title: string;
|
|
201
|
+
} | null;
|
|
202
|
+
assignees: {
|
|
203
|
+
login: string;
|
|
204
|
+
}[];
|
|
205
|
+
comments_data: GitHubComment[];
|
|
206
|
+
linked_issues: number[];
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Convert a pre-fetched GitHub issue or PR into a generic RawWorkItem.
|
|
210
|
+
*/
|
|
211
|
+
declare function githubToRawWorkItem(issue: GitHubIssue): RawWorkItem;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Linear label shape.
|
|
215
|
+
*/
|
|
216
|
+
interface LinearLabel {
|
|
217
|
+
id: string;
|
|
218
|
+
name: string;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Linear comment shape.
|
|
222
|
+
*/
|
|
223
|
+
interface LinearComment {
|
|
224
|
+
body: string;
|
|
225
|
+
user: {
|
|
226
|
+
name: string;
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Linear relation shape (blocking/blocked-by/related).
|
|
231
|
+
*/
|
|
232
|
+
interface LinearRelation {
|
|
233
|
+
type: string;
|
|
234
|
+
relatedIssue: {
|
|
235
|
+
id: string;
|
|
236
|
+
identifier: string;
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Minimal Linear issue shape accepted by the adapter.
|
|
241
|
+
* Represents pre-fetched data from the Linear GraphQL API.
|
|
242
|
+
*/
|
|
243
|
+
interface LinearIssue {
|
|
244
|
+
id: string;
|
|
245
|
+
identifier: string;
|
|
246
|
+
title: string;
|
|
247
|
+
description: string | null;
|
|
248
|
+
priority: number;
|
|
249
|
+
state: {
|
|
250
|
+
id: string;
|
|
251
|
+
name: string;
|
|
252
|
+
};
|
|
253
|
+
labels: {
|
|
254
|
+
nodes: LinearLabel[];
|
|
255
|
+
};
|
|
256
|
+
createdAt: string;
|
|
257
|
+
updatedAt: string;
|
|
258
|
+
url: string;
|
|
259
|
+
branchName: string | null;
|
|
260
|
+
comments: {
|
|
261
|
+
nodes: LinearComment[];
|
|
262
|
+
};
|
|
263
|
+
relations: {
|
|
264
|
+
nodes: LinearRelation[];
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Convert a pre-fetched Linear issue into a generic RawWorkItem.
|
|
269
|
+
*/
|
|
270
|
+
declare function linearToRawWorkItem(issue: LinearIssue): RawWorkItem;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Manual input shape — accepts free-text with optional metadata.
|
|
274
|
+
*/
|
|
275
|
+
interface ManualInput {
|
|
276
|
+
title: string;
|
|
277
|
+
description?: string;
|
|
278
|
+
labels?: string[];
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Convert a manual text input into a generic RawWorkItem.
|
|
282
|
+
* Generates a unique ID with a `manual-` prefix.
|
|
283
|
+
*/
|
|
284
|
+
declare function manualToRawWorkItem(input: ManualInput): RawWorkItem;
|
|
285
|
+
|
|
286
|
+
interface AnalysisRequest {
|
|
287
|
+
prompt: string;
|
|
288
|
+
systemPrompt?: string;
|
|
289
|
+
responseSchema: z.ZodType;
|
|
290
|
+
model?: string;
|
|
291
|
+
maxTokens?: number;
|
|
292
|
+
}
|
|
293
|
+
interface AnalysisResponse<T> {
|
|
294
|
+
result: T;
|
|
295
|
+
tokenUsage: {
|
|
296
|
+
inputTokens: number;
|
|
297
|
+
outputTokens: number;
|
|
298
|
+
totalTokens: number;
|
|
299
|
+
};
|
|
300
|
+
model: string;
|
|
301
|
+
latencyMs: number;
|
|
302
|
+
}
|
|
303
|
+
interface AnalysisProvider {
|
|
304
|
+
analyze<T>(request: AnalysisRequest): Promise<AnalysisResponse<T>>;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
interface AnthropicProviderOptions {
|
|
308
|
+
apiKey: string;
|
|
309
|
+
defaultModel?: string;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* AnalysisProvider implementation backed by the Anthropic Messages API.
|
|
313
|
+
*
|
|
314
|
+
* Uses the tool_use pattern to extract structured JSON that conforms to
|
|
315
|
+
* a caller-supplied Zod schema.
|
|
316
|
+
*/
|
|
317
|
+
declare class AnthropicAnalysisProvider implements AnalysisProvider {
|
|
318
|
+
private readonly client;
|
|
319
|
+
private readonly defaultModel;
|
|
320
|
+
constructor(options: AnthropicProviderOptions);
|
|
321
|
+
analyze<T>(request: AnalysisRequest): Promise<AnalysisResponse<T>>;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
interface OpenAICompatibleProviderOptions {
|
|
325
|
+
/** API key (some local servers accept any string, e.g., 'ollama'). */
|
|
326
|
+
apiKey: string;
|
|
327
|
+
/** Base URL for the OpenAI-compatible endpoint (e.g., http://localhost:11434/v1). */
|
|
328
|
+
baseUrl: string;
|
|
329
|
+
/** Default model name (e.g., 'deepseek-coder-v2'). */
|
|
330
|
+
defaultModel?: string;
|
|
331
|
+
/** Request timeout in ms (default: 90000). */
|
|
332
|
+
timeoutMs?: number;
|
|
333
|
+
/**
|
|
334
|
+
* String appended to user prompts for structured-output requests.
|
|
335
|
+
* Useful for disabling thinking/reasoning modes (e.g., '/no_think' for Qwen3).
|
|
336
|
+
*/
|
|
337
|
+
promptSuffix?: string;
|
|
338
|
+
/**
|
|
339
|
+
* Whether to send `response_format: { type: 'json_schema' }` with the full
|
|
340
|
+
* schema to the server for grammar-constrained decoding. When false, relies
|
|
341
|
+
* on the system prompt alone to produce valid JSON. Default: true.
|
|
342
|
+
*/
|
|
343
|
+
jsonMode?: boolean;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* AnalysisProvider for OpenAI-compatible endpoints (Ollama, LM Studio, vLLM, etc.).
|
|
347
|
+
*
|
|
348
|
+
* Uses JSON mode with a system prompt instructing structured output.
|
|
349
|
+
* Falls back to parsing raw text as JSON if the model doesn't support
|
|
350
|
+
* response_format natively.
|
|
351
|
+
*/
|
|
352
|
+
declare class OpenAICompatibleAnalysisProvider implements AnalysisProvider {
|
|
353
|
+
private readonly client;
|
|
354
|
+
private readonly defaultModel;
|
|
355
|
+
private readonly promptSuffix;
|
|
356
|
+
private readonly jsonMode;
|
|
357
|
+
constructor(options: OpenAICompatibleProviderOptions);
|
|
358
|
+
analyze<T>(request: AnalysisRequest): Promise<AnalysisResponse<T>>;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
interface ClaudeCliProviderOptions {
|
|
362
|
+
/** Path to the claude binary (default: 'claude') */
|
|
363
|
+
command?: string | undefined;
|
|
364
|
+
/** Model to use (default: let the CLI decide) */
|
|
365
|
+
defaultModel?: string | undefined;
|
|
366
|
+
/** Request timeout in ms (default: 180000) */
|
|
367
|
+
timeoutMs?: number | undefined;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* AnalysisProvider that uses the Claude CLI for structured analysis.
|
|
371
|
+
*
|
|
372
|
+
* This avoids the need for an API key — the CLI manages its own
|
|
373
|
+
* authentication. Structured output is enforced via --json-schema.
|
|
374
|
+
*/
|
|
375
|
+
declare class ClaudeCliAnalysisProvider implements AnalysisProvider {
|
|
376
|
+
private readonly command;
|
|
377
|
+
private readonly defaultModel;
|
|
378
|
+
private readonly timeoutMs;
|
|
379
|
+
constructor(options?: ClaudeCliProviderOptions);
|
|
380
|
+
analyze<T>(request: AnalysisRequest): Promise<AnalysisResponse<T>>;
|
|
381
|
+
private runClaude;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Validates affected systems against the knowledge graph.
|
|
386
|
+
*
|
|
387
|
+
* For each system name from the LLM output, searches the graph for matching
|
|
388
|
+
* module or file nodes and enriches with transitive dependencies, test coverage,
|
|
389
|
+
* and ownership information.
|
|
390
|
+
*/
|
|
391
|
+
declare class GraphValidator {
|
|
392
|
+
private readonly store;
|
|
393
|
+
private cachedModuleNodes;
|
|
394
|
+
private cachedFileNodes;
|
|
395
|
+
constructor(store: GraphStore);
|
|
396
|
+
/**
|
|
397
|
+
* Validate and enrich a list of affected system names against the graph.
|
|
398
|
+
*/
|
|
399
|
+
validate(systems: Array<{
|
|
400
|
+
name: string;
|
|
401
|
+
}>): AffectedSystem[];
|
|
402
|
+
private resolveSystem;
|
|
403
|
+
/**
|
|
404
|
+
* Simple fuzzy scoring: exact match = 1, contains = 0.7, substring overlap.
|
|
405
|
+
*/
|
|
406
|
+
private fuzzyScore;
|
|
407
|
+
private resolveTransitiveDeps;
|
|
408
|
+
private resolveTestCoverage;
|
|
409
|
+
private resolveOwner;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Enrich a RawWorkItem into a full EnrichedSpec via LLM analysis and graph validation.
|
|
414
|
+
*
|
|
415
|
+
* 1. Calls the AnalysisProvider with SEL prompts and response schema
|
|
416
|
+
* 2. Parses the LLM response into a partial EnrichedSpec
|
|
417
|
+
* 3. Validates affected systems against the knowledge graph
|
|
418
|
+
* 4. Returns a fully populated EnrichedSpec
|
|
419
|
+
*/
|
|
420
|
+
declare function enrich(item: RawWorkItem, provider: AnalysisProvider, graphValidator: GraphValidator): Promise<EnrichedSpec>;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Score an enriched spec using the Complexity Modeling Layer (CML).
|
|
424
|
+
*
|
|
425
|
+
* Combines structural (graph-based blast radius), semantic (SEL enrichment
|
|
426
|
+
* fields), and historical (past execution outcomes) dimensions into a single
|
|
427
|
+
* {@link ComplexityScore}.
|
|
428
|
+
*/
|
|
429
|
+
declare function score(spec: EnrichedSpec, store: GraphStore): ComplexityScore;
|
|
430
|
+
|
|
431
|
+
interface StructuralResult {
|
|
432
|
+
score: number;
|
|
433
|
+
blastRadius: BlastRadius;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Compute structural complexity by running CascadeSimulator for every
|
|
437
|
+
* affected system that has a resolved graph node ID.
|
|
438
|
+
*
|
|
439
|
+
* The score is the probability-weighted sum of affected nodes across all
|
|
440
|
+
* systems, normalized against a ceiling of {@link NORMALIZATION_CEILING}.
|
|
441
|
+
*/
|
|
442
|
+
declare function computeStructuralComplexity(spec: EnrichedSpec, store: GraphStore): StructuralResult;
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Compute semantic complexity from the SEL enrichment fields.
|
|
446
|
+
*
|
|
447
|
+
* Each dimension uses a diminishing-returns curve `1 - exp(-count * 0.3)`
|
|
448
|
+
* so that the first few items have the biggest impact and marginal
|
|
449
|
+
* additions produce less incremental score.
|
|
450
|
+
*
|
|
451
|
+
* Returns a value in [0, 1].
|
|
452
|
+
*/
|
|
453
|
+
declare function computeSemanticComplexity(spec: EnrichedSpec): number;
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Convert a {@link ComplexityScore} into an array of {@link ConcernSignal}s
|
|
457
|
+
* that downstream routing logic can use for escalation decisions.
|
|
458
|
+
*
|
|
459
|
+
* Returns an empty array when the score is below all thresholds.
|
|
460
|
+
*/
|
|
461
|
+
declare function scoreToConcernSignals(score: ComplexityScore): ConcernSignal[];
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Run graph-only pre-execution simulation checks.
|
|
465
|
+
*
|
|
466
|
+
* Uses CascadeSimulator blast radius and impact grouping to produce a
|
|
467
|
+
* SimulationResult without any LLM calls. Intended for quick-fix and
|
|
468
|
+
* diagnostic tier issues where speed matters.
|
|
469
|
+
*
|
|
470
|
+
* Deterministic and fast (<2s for typical graphs).
|
|
471
|
+
*/
|
|
472
|
+
declare function runGraphOnlyChecks(spec: EnrichedSpec, score: ComplexityScore, store: GraphStore): SimulationResult;
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Run full LLM pre-execution simulation.
|
|
476
|
+
*
|
|
477
|
+
* Combines graph-only checks with LLM-driven plan expansion, failure
|
|
478
|
+
* injection, and test projection. Intended for guided-change and
|
|
479
|
+
* simulation-required tier issues.
|
|
480
|
+
*/
|
|
481
|
+
declare function runLlmSimulation(spec: EnrichedSpec, score: ComplexityScore, store: GraphStore, provider: AnalysisProvider, model?: string): Promise<SimulationResult>;
|
|
482
|
+
|
|
483
|
+
interface PeslSimulatorOptions {
|
|
484
|
+
/** Override model for PESL LLM calls. */
|
|
485
|
+
model?: string;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Top-level PESL simulator that routes to graph-only or full LLM simulation
|
|
489
|
+
* based on scope tier and CML recommended route.
|
|
490
|
+
*
|
|
491
|
+
* Tiered behavior (per D5 in spec):
|
|
492
|
+
* - quick-fix / diagnostic: graph-only checks (CascadeSimulator + impact)
|
|
493
|
+
* - guided-change: full LLM simulation (plan expansion, failure injection, test projection)
|
|
494
|
+
* - simulation-required override: full LLM simulation regardless of tier
|
|
495
|
+
*/
|
|
496
|
+
declare class PeslSimulator {
|
|
497
|
+
private readonly provider;
|
|
498
|
+
private readonly store;
|
|
499
|
+
private readonly options;
|
|
500
|
+
constructor(provider: AnalysisProvider, store: GraphStore, options?: PeslSimulatorOptions);
|
|
501
|
+
/**
|
|
502
|
+
* Run pre-execution simulation for a spec.
|
|
503
|
+
*
|
|
504
|
+
* @param spec - Enriched spec from SEL
|
|
505
|
+
* @param score - Complexity score from CML
|
|
506
|
+
* @param tier - Scope tier of the issue
|
|
507
|
+
* @returns SimulationResult with tier, confidence, and abort recommendation
|
|
508
|
+
*/
|
|
509
|
+
simulate(spec: EnrichedSpec, score: ComplexityScore, tier: ScopeTier): Promise<SimulationResult>;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/** Task type categorization for specialization tracking. */
|
|
513
|
+
type TaskType = 'feature' | 'bugfix' | 'refactor' | 'docs' | 'test' | 'chore';
|
|
514
|
+
/**
|
|
515
|
+
* Execution outcome -- result of a worker running an issue.
|
|
516
|
+
* Ingested into the graph as an 'execution_outcome' node.
|
|
517
|
+
*/
|
|
518
|
+
interface ExecutionOutcome {
|
|
519
|
+
/** Unique ID for this outcome (e.g., `outcome:<issueId>:<attempt>`) */
|
|
520
|
+
id: string;
|
|
521
|
+
/** ID of the issue that was executed */
|
|
522
|
+
issueId: string;
|
|
523
|
+
/** Human-readable identifier (e.g., 'PROJ-123') */
|
|
524
|
+
identifier: string;
|
|
525
|
+
/** Execution result */
|
|
526
|
+
result: 'success' | 'failure';
|
|
527
|
+
/** Number of retry attempts before this outcome */
|
|
528
|
+
retryCount: number;
|
|
529
|
+
/** Failure reasons (empty for success) */
|
|
530
|
+
failureReasons: string[];
|
|
531
|
+
/** Execution duration in milliseconds */
|
|
532
|
+
durationMs: number;
|
|
533
|
+
/** ID of the linked EnrichedSpec, if one was produced */
|
|
534
|
+
linkedSpecId: string | null;
|
|
535
|
+
/** Affected system graph node IDs from the enriched spec */
|
|
536
|
+
affectedSystemNodeIds: string[];
|
|
537
|
+
/** ISO timestamp of when the outcome was recorded */
|
|
538
|
+
timestamp: string;
|
|
539
|
+
/**
|
|
540
|
+
* Optional persona or agent identifier that produced this outcome
|
|
541
|
+
* (e.g. 'task-executor'). When present the ingestor records it in
|
|
542
|
+
* the graph node's metadata so effectiveness analytics can attribute
|
|
543
|
+
* successes and failures to the responsible agent.
|
|
544
|
+
*/
|
|
545
|
+
agentPersona?: string;
|
|
546
|
+
/** Task type categorization (e.g., 'feature', 'bugfix', 'refactor', 'docs'). */
|
|
547
|
+
taskType?: TaskType;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
interface OutcomeIngestResult {
|
|
551
|
+
nodesAdded: number;
|
|
552
|
+
edgesAdded: number;
|
|
553
|
+
errors: string[];
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Ingests execution outcomes into the knowledge graph.
|
|
557
|
+
*
|
|
558
|
+
* Creates an 'execution_outcome' node for each outcome with metadata
|
|
559
|
+
* containing result, retry count, failure reasons, duration, and linked
|
|
560
|
+
* spec ID. Creates 'outcome_of' edges to each affected system node
|
|
561
|
+
* that exists in the graph.
|
|
562
|
+
*/
|
|
563
|
+
declare class ExecutionOutcomeConnector {
|
|
564
|
+
private readonly store;
|
|
565
|
+
constructor(store: GraphStore);
|
|
566
|
+
ingest(outcome: ExecutionOutcome): OutcomeIngestResult;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Compute historical complexity from past execution outcomes in the graph.
|
|
571
|
+
*
|
|
572
|
+
* For each affected system with a graph node ID, queries the graph for
|
|
573
|
+
* 'execution_outcome' nodes linked via 'outcome_of' edges. Computes
|
|
574
|
+
* a smoothed failure rate per system, then returns the maximum across
|
|
575
|
+
* all systems.
|
|
576
|
+
*
|
|
577
|
+
* Returns a value in [0, 1]. Returns 0 when no outcomes exist.
|
|
578
|
+
*/
|
|
579
|
+
declare function computeHistoricalComplexity(spec: EnrichedSpec, store: GraphStore): number;
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Result of preprocessing an issue through the intelligence pipeline.
|
|
583
|
+
*/
|
|
584
|
+
interface PreprocessResult {
|
|
585
|
+
/** Enriched spec from SEL, or null if SEL was skipped */
|
|
586
|
+
spec: EnrichedSpec | null;
|
|
587
|
+
/** Complexity score from CML, or null if CML was skipped */
|
|
588
|
+
score: ComplexityScore | null;
|
|
589
|
+
/** Concern signals derived from complexity score (empty if CML skipped) */
|
|
590
|
+
signals: ConcernSignal[];
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Composes SEL, CML, and signal conversion into a single pipeline.
|
|
594
|
+
*
|
|
595
|
+
* Tier-based behavior:
|
|
596
|
+
* - `autoExecute` tiers: skip entirely (no LLM cost)
|
|
597
|
+
* - `alwaysHuman` tiers: run SEL for enrichment context, skip CML (routing already decided)
|
|
598
|
+
* - `signalGated` tiers: full pipeline (SEL → CML → signals)
|
|
599
|
+
*/
|
|
600
|
+
declare class IntelligencePipeline {
|
|
601
|
+
private readonly provider;
|
|
602
|
+
private readonly graphValidator;
|
|
603
|
+
private readonly store;
|
|
604
|
+
private readonly simulator;
|
|
605
|
+
private readonly outcomeConnector;
|
|
606
|
+
constructor(provider: AnalysisProvider, store: GraphStore, options?: {
|
|
607
|
+
peslModel?: string;
|
|
608
|
+
});
|
|
609
|
+
/**
|
|
610
|
+
* Enrich a raw work item into an EnrichedSpec via LLM + graph validation.
|
|
611
|
+
*/
|
|
612
|
+
enrich(item: RawWorkItem): Promise<EnrichedSpec>;
|
|
613
|
+
/**
|
|
614
|
+
* Score an enriched spec using graph-based structural + semantic analysis.
|
|
615
|
+
* Synchronous — no LLM calls.
|
|
616
|
+
*/
|
|
617
|
+
score(spec: EnrichedSpec): ComplexityScore;
|
|
618
|
+
/**
|
|
619
|
+
* Run pre-execution simulation for a spec.
|
|
620
|
+
*/
|
|
621
|
+
simulate(spec: EnrichedSpec, score: ComplexityScore, tier?: ScopeTier): Promise<SimulationResult>;
|
|
622
|
+
/**
|
|
623
|
+
* Record an execution outcome in the knowledge graph.
|
|
624
|
+
* Called by the orchestrator after a worker exits.
|
|
625
|
+
*/
|
|
626
|
+
recordOutcome(outcome: ExecutionOutcome): OutcomeIngestResult;
|
|
627
|
+
/**
|
|
628
|
+
* Preprocess an issue through the intelligence pipeline.
|
|
629
|
+
*
|
|
630
|
+
* Behavior depends on which escalation tier the issue's scope falls into:
|
|
631
|
+
* - `autoExecute`: returns immediately with null spec/score and empty signals
|
|
632
|
+
* - `alwaysHuman`: runs SEL for enrichment context (human gets pre-analyzed view),
|
|
633
|
+
* skips CML, returns empty signals (routing stays needs-human)
|
|
634
|
+
* - `signalGated`: runs full SEL → CML → signals pipeline
|
|
635
|
+
*/
|
|
636
|
+
preprocessIssue(issue: Issue, scopeTier: _harness_engineering_types.ScopeTier, escalationConfig: EscalationConfig): Promise<PreprocessResult>;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Agent Effectiveness Introspection types.
|
|
641
|
+
*
|
|
642
|
+
* Given a graph populated with `execution_outcome` nodes (each carrying an
|
|
643
|
+
* `agentPersona` tag and linked to affected systems via `outcome_of` edges),
|
|
644
|
+
* these structures describe per-persona accuracy, blind spots, and
|
|
645
|
+
* persona recommendations for new issues.
|
|
646
|
+
*/
|
|
647
|
+
/**
|
|
648
|
+
* Smoothed success rate for a single `(persona, systemNodeId)` pair.
|
|
649
|
+
*
|
|
650
|
+
* `successRate` uses Laplace smoothing with α = 1:
|
|
651
|
+
* (successes + 1) / (successes + failures + 2)
|
|
652
|
+
*
|
|
653
|
+
* This matches the bias of `computeHistoricalComplexity` and prevents a
|
|
654
|
+
* single outcome from claiming 0% or 100% certainty.
|
|
655
|
+
*/
|
|
656
|
+
interface PersonaEffectivenessScore {
|
|
657
|
+
persona: string;
|
|
658
|
+
systemNodeId: string;
|
|
659
|
+
successes: number;
|
|
660
|
+
failures: number;
|
|
661
|
+
/** Laplace-smoothed success rate in [0, 1]. */
|
|
662
|
+
successRate: number;
|
|
663
|
+
/** Total observations (successes + failures). */
|
|
664
|
+
sampleSize: number;
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* A `(persona, system)` pair where the persona consistently fails.
|
|
668
|
+
*
|
|
669
|
+
* Uses the *raw* failure rate `failures / (failures + successes)` so the
|
|
670
|
+
* thresholds remain intuitive (e.g. "at least 50% failure with 2+ failures").
|
|
671
|
+
*/
|
|
672
|
+
interface BlindSpot {
|
|
673
|
+
persona: string;
|
|
674
|
+
systemNodeId: string;
|
|
675
|
+
failures: number;
|
|
676
|
+
successes: number;
|
|
677
|
+
/** Raw failure rate: failures / (failures + successes). */
|
|
678
|
+
failureRate: number;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Recommendation for which persona to route a new issue to, given the list
|
|
682
|
+
* of affected systems (graph node IDs) the issue will touch.
|
|
683
|
+
*
|
|
684
|
+
* `score` is the mean Laplace-smoothed success rate across the requested
|
|
685
|
+
* systems. Systems for which the persona has no history contribute the
|
|
686
|
+
* neutral prior 0.5, preventing over-confidence on partial data.
|
|
687
|
+
*/
|
|
688
|
+
interface PersonaRecommendation {
|
|
689
|
+
persona: string;
|
|
690
|
+
/** Mean smoothed success rate across the requested systems, in [0, 1]. */
|
|
691
|
+
score: number;
|
|
692
|
+
/** Number of requested systems with at least one observation for this persona. */
|
|
693
|
+
coveredSystems: number;
|
|
694
|
+
/** Number of requested systems with zero history for this persona. */
|
|
695
|
+
unknownSystems: number;
|
|
696
|
+
/** Total observations for this persona across the requested systems. */
|
|
697
|
+
totalSamples: number;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Per-`(persona, systemNodeId)` effectiveness scores.
|
|
702
|
+
*
|
|
703
|
+
* Results are sorted by `successRate` descending, then by `sampleSize`
|
|
704
|
+
* descending, for stable deterministic iteration.
|
|
705
|
+
*/
|
|
706
|
+
declare function computePersonaEffectiveness(store: GraphStore, opts?: {
|
|
707
|
+
persona?: string;
|
|
708
|
+
systemNodeId?: string;
|
|
709
|
+
}): PersonaEffectivenessScore[];
|
|
710
|
+
/**
|
|
711
|
+
* Blind spots: `(persona, system)` pairs where failures accumulate.
|
|
712
|
+
*
|
|
713
|
+
* Uses the *raw* failure rate (not smoothed) so thresholds stay intuitive.
|
|
714
|
+
* A pair must satisfy BOTH `failures >= minFailures` AND
|
|
715
|
+
* `rawFailureRate >= minFailureRate`.
|
|
716
|
+
*
|
|
717
|
+
* Results are sorted by `failureRate` descending, then by `failures` descending.
|
|
718
|
+
*/
|
|
719
|
+
declare function detectBlindSpots(store: GraphStore, opts?: {
|
|
720
|
+
persona?: string;
|
|
721
|
+
minFailures?: number;
|
|
722
|
+
minFailureRate?: number;
|
|
723
|
+
}): BlindSpot[];
|
|
724
|
+
/**
|
|
725
|
+
* Recommend personas to route a new issue to, given its affected systems.
|
|
726
|
+
*
|
|
727
|
+
* For each candidate persona, compute the mean Laplace-smoothed success rate
|
|
728
|
+
* across `systemNodeIds`. Systems with no observations for the candidate
|
|
729
|
+
* contribute the neutral prior 0.5.
|
|
730
|
+
*
|
|
731
|
+
* When `candidatePersonas` is omitted, the candidate set is the set of
|
|
732
|
+
* personas with at least one persona-attributed outcome in the graph.
|
|
733
|
+
* When none exist and no candidates are passed in, returns `[]`.
|
|
734
|
+
*
|
|
735
|
+
* Results are sorted by `score` descending, ties broken by `totalSamples`
|
|
736
|
+
* descending.
|
|
737
|
+
*/
|
|
738
|
+
declare function recommendPersona(store: GraphStore, opts: {
|
|
739
|
+
systemNodeIds: string[];
|
|
740
|
+
candidatePersonas?: string[];
|
|
741
|
+
minSamples?: number;
|
|
742
|
+
}): PersonaRecommendation[];
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Persistent Agent Specialization types.
|
|
746
|
+
*
|
|
747
|
+
* Extends the effectiveness module with temporal awareness, task-type
|
|
748
|
+
* categorization, expertise levels, and dynamic persona weighting.
|
|
749
|
+
*/
|
|
750
|
+
|
|
751
|
+
/** Expertise tier derived from sample size and success rate. */
|
|
752
|
+
type ExpertiseLevel = 'novice' | 'competent' | 'proficient' | 'expert';
|
|
753
|
+
/**
|
|
754
|
+
* Composite specialization score for a (persona, system, taskType) tuple.
|
|
755
|
+
* All values are in [0, 1].
|
|
756
|
+
*/
|
|
757
|
+
interface SpecializationScore {
|
|
758
|
+
/** Temporally-weighted success rate (recent outcomes weighted higher). */
|
|
759
|
+
temporalSuccessRate: number;
|
|
760
|
+
/** Consistency score: 1 - stddev of rolling success windows. */
|
|
761
|
+
consistencyScore: number;
|
|
762
|
+
/** Volume bonus: log-scaled sample count, capped at 1.0. */
|
|
763
|
+
volumeBonus: number;
|
|
764
|
+
/** Composite score: weighted combination of the above. */
|
|
765
|
+
composite: number;
|
|
766
|
+
}
|
|
767
|
+
/** A single specialization entry for a (persona, system, taskType) bucket. */
|
|
768
|
+
interface SpecializationEntry {
|
|
769
|
+
persona: string;
|
|
770
|
+
systemNodeId: string;
|
|
771
|
+
taskType: string;
|
|
772
|
+
score: SpecializationScore;
|
|
773
|
+
expertiseLevel: ExpertiseLevel;
|
|
774
|
+
sampleSize: number;
|
|
775
|
+
/** ISO timestamp of most recent outcome in this bucket. */
|
|
776
|
+
lastOutcome: string;
|
|
777
|
+
}
|
|
778
|
+
/** Full specialization profile for a persona across all systems/task-types. */
|
|
779
|
+
interface SpecializationProfile {
|
|
780
|
+
persona: string;
|
|
781
|
+
/** Per-(system, taskType) specialization entries. */
|
|
782
|
+
entries: SpecializationEntry[];
|
|
783
|
+
/** Top areas of expertise (highest composite scores). */
|
|
784
|
+
strengths: SpecializationEntry[];
|
|
785
|
+
/** Areas of consistent failure. */
|
|
786
|
+
weaknesses: SpecializationEntry[];
|
|
787
|
+
/** Overall expertise level across all entries. */
|
|
788
|
+
overallLevel: ExpertiseLevel;
|
|
789
|
+
/** ISO timestamp when this profile was computed. */
|
|
790
|
+
computedAt: string;
|
|
791
|
+
}
|
|
792
|
+
/** Weighted persona recommendation incorporating specialization scores. */
|
|
793
|
+
interface WeightedRecommendation {
|
|
794
|
+
persona: string;
|
|
795
|
+
/** Base score from existing recommendPersona(). */
|
|
796
|
+
baseScore: number;
|
|
797
|
+
/** Specialization multiplier [0.5, 1.5]. */
|
|
798
|
+
specializationMultiplier: number;
|
|
799
|
+
/** Final weighted score: baseScore * specializationMultiplier. */
|
|
800
|
+
weightedScore: number;
|
|
801
|
+
/** Expertise level for the requested systems/task-type. */
|
|
802
|
+
expertiseLevel: ExpertiseLevel;
|
|
803
|
+
/** Number of requested systems with specialization data. */
|
|
804
|
+
specializedSystems: number;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Temporal decay functions for specialization scoring.
|
|
809
|
+
*
|
|
810
|
+
* Uses exponential decay to weight recent outcomes more heavily than old ones.
|
|
811
|
+
* The decay formula: weight = e^(-ln(2) / halfLifeDays * ageDays)
|
|
812
|
+
*/
|
|
813
|
+
/** Configuration for temporal decay calculations. */
|
|
814
|
+
interface TemporalConfig {
|
|
815
|
+
/** Half-life in days (default 30). After this many days, an outcome's weight is halved. */
|
|
816
|
+
halfLifeDays: number;
|
|
817
|
+
/** Reference timestamp for decay calculation (default: now). */
|
|
818
|
+
referenceTime?: string;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Compute exponential decay weight for an outcome at a given age.
|
|
822
|
+
* Returns 1.0 at age 0, 0.5 at halfLifeDays, 0.25 at 2*halfLifeDays, etc.
|
|
823
|
+
*/
|
|
824
|
+
declare function decayWeight(ageDays: number, halfLifeDays: number): number;
|
|
825
|
+
/**
|
|
826
|
+
* Compute temporally-weighted success rate from timestamped outcomes.
|
|
827
|
+
*
|
|
828
|
+
* Returns 0.5 (neutral prior) when no outcomes are provided.
|
|
829
|
+
* Uses Laplace smoothing with decay-weighted pseudo-counts.
|
|
830
|
+
*/
|
|
831
|
+
declare function temporalSuccessRate(outcomes: ReadonlyArray<{
|
|
832
|
+
result: 'success' | 'failure';
|
|
833
|
+
timestamp: string;
|
|
834
|
+
}>, config: TemporalConfig): number;
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Specialization scorer — computes expertise scores for (persona, system, taskType) tuples.
|
|
838
|
+
*
|
|
839
|
+
* Builds on the effectiveness module by adding temporal decay, task-type
|
|
840
|
+
* categorization, consistency scoring, and dynamic persona weighting.
|
|
841
|
+
*/
|
|
842
|
+
|
|
843
|
+
interface SpecializationOptions {
|
|
844
|
+
persona?: string;
|
|
845
|
+
systemNodeId?: string;
|
|
846
|
+
taskType?: TaskType;
|
|
847
|
+
temporal?: TemporalConfig;
|
|
848
|
+
minSamples?: number;
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Classify expertise level from sample size and success rate.
|
|
852
|
+
*/
|
|
853
|
+
declare function computeExpertiseLevel(sampleSize: number, successRate: number): ExpertiseLevel;
|
|
854
|
+
/**
|
|
855
|
+
* Compute specialization entries for (persona, system, taskType) tuples.
|
|
856
|
+
*/
|
|
857
|
+
declare function computeSpecialization(store: GraphStore, opts?: SpecializationOptions): SpecializationEntry[];
|
|
858
|
+
/**
|
|
859
|
+
* Build a full specialization profile for a persona.
|
|
860
|
+
*/
|
|
861
|
+
declare function buildSpecializationProfile(store: GraphStore, persona: string, opts?: Omit<SpecializationOptions, 'persona'>): SpecializationProfile;
|
|
862
|
+
/**
|
|
863
|
+
* Weighted persona recommendation incorporating specialization scores.
|
|
864
|
+
*
|
|
865
|
+
* Wraps the existing `recommendPersona()` and applies specialization
|
|
866
|
+
* multipliers to produce weighted scores.
|
|
867
|
+
*/
|
|
868
|
+
declare function weightedRecommendPersona(store: GraphStore, opts: {
|
|
869
|
+
systemNodeIds: string[];
|
|
870
|
+
taskType?: TaskType;
|
|
871
|
+
candidatePersonas?: string[];
|
|
872
|
+
minSamples?: number;
|
|
873
|
+
temporal?: TemporalConfig;
|
|
874
|
+
}): WeightedRecommendation[];
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* Profile persistence — load/save specialization profiles to disk.
|
|
878
|
+
*
|
|
879
|
+
* Profiles are stored at `.harness/specialization-profiles.json` and survive
|
|
880
|
+
* across sessions so agents retain their accumulated expertise.
|
|
881
|
+
*/
|
|
882
|
+
|
|
883
|
+
/** Persisted store of specialization profiles. */
|
|
884
|
+
interface ProfileStore {
|
|
885
|
+
profiles: Record<string, SpecializationProfile>;
|
|
886
|
+
computedAt: string;
|
|
887
|
+
version: 1;
|
|
888
|
+
}
|
|
889
|
+
/** Load profiles from disk. Returns empty store if file doesn't exist. */
|
|
890
|
+
declare function loadProfiles(projectRoot: string): ProfileStore;
|
|
891
|
+
/** Save profiles to disk at .harness/specialization-profiles.json. */
|
|
892
|
+
declare function saveProfiles(projectRoot: string, store: ProfileStore): void;
|
|
893
|
+
/**
|
|
894
|
+
* Recompute and persist profiles for all personas with outcomes.
|
|
895
|
+
*
|
|
896
|
+
* Discovers all persona names from execution_outcome nodes in the graph,
|
|
897
|
+
* builds a specialization profile for each, and saves the result.
|
|
898
|
+
*/
|
|
899
|
+
declare function refreshProfiles(projectRoot: string, graphStore: GraphStore, opts?: Omit<SpecializationOptions, 'persona'>): ProfileStore;
|
|
900
|
+
|
|
901
|
+
export { type AffectedSystem, type AnalysisProvider, type AnalysisRequest, type AnalysisResponse, AnthropicAnalysisProvider, type BlastRadius, type BlindSpot, ClaudeCliAnalysisProvider, type ComplexityScore, type EnrichedSpec, type ExecutionOutcome, ExecutionOutcomeConnector, type ExpertiseLevel, type GitHubIssue, GraphValidator, IntelligencePipeline, type JiraIssue, type LinearIssue, type ManualInput, OpenAICompatibleAnalysisProvider, type OutcomeIngestResult, type PersonaEffectivenessScore, type PersonaRecommendation, PeslSimulator, type PreprocessResult, type ProfileStore, type RawWorkItem, type SimulationResult, type SpecializationEntry, type SpecializationProfile, type SpecializationScore, type TaskType, type TemporalConfig, type WeightedRecommendation, buildSpecializationProfile, computeExpertiseLevel, computeHistoricalComplexity, computePersonaEffectiveness, computeSemanticComplexity, computeSpecialization, computeStructuralComplexity, decayWeight, detectBlindSpots, enrich, githubToRawWorkItem, jiraToRawWorkItem, linearToRawWorkItem, loadProfiles, manualToRawWorkItem, recommendPersona, refreshProfiles, runGraphOnlyChecks, runLlmSimulation, saveProfiles, score as scoreCML, scoreToConcernSignals, temporalSuccessRate, toRawWorkItem, weightedRecommendPersona };
|