@harness-engineering/intelligence 0.6.0 → 0.7.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.js CHANGED
@@ -31,13 +31,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ACCEPTANCE_EVAL_SYSTEM_PROMPT: () => ACCEPTANCE_EVAL_SYSTEM_PROMPT,
34
+ AUTO_EXECUTE_CATEGORIES: () => AUTO_EXECUTE_CATEGORIES,
34
35
  AcceptanceEvaluator: () => AcceptanceEvaluator,
35
36
  AnthropicAnalysisProvider: () => AnthropicAnalysisProvider,
37
+ BLAST_TOLERANCE_ABS: () => BLAST_TOLERANCE_ABS,
38
+ BLAST_TOLERANCE_FACTOR: () => BLAST_TOLERANCE_FACTOR,
36
39
  ClaudeCliAnalysisProvider: () => ClaudeCliAnalysisProvider,
37
40
  DEFAULT_DEGRADE_AT_PCT: () => DEFAULT_DEGRADE_AT_PCT,
41
+ DEFAULT_RATCHET_CONFIG: () => DEFAULT_RATCHET_CONFIG,
42
+ DEFAULT_RETROSPECTIVE_CONFIG: () => DEFAULT_RETROSPECTIVE_CONFIG,
43
+ DEPTH_BY_LEVEL: () => DEPTH_BY_LEVEL,
38
44
  ExecutionOutcomeConnector: () => ExecutionOutcomeConnector,
39
45
  GraphValidator: () => GraphValidator,
40
46
  IntelligencePipeline: () => IntelligencePipeline,
47
+ LEVEL_RANK: () => LEVEL_RANK,
41
48
  OUTCOME_EVAL_SYSTEM_PROMPT: () => OUTCOME_EVAL_SYSTEM_PROMPT,
42
49
  OpenAICompatibleAnalysisProvider: () => OpenAICompatibleAnalysisProvider,
43
50
  OutcomeEvaluator: () => OutcomeEvaluator,
@@ -46,7 +53,9 @@ __export(index_exports, {
46
53
  SENSITIVE_BLAST_THRESHOLD: () => SENSITIVE_BLAST_THRESHOLD,
47
54
  STATIC_WEIGHTS: () => STATIC_WEIGHTS,
48
55
  TIER_RANK: () => TIER_RANK,
56
+ V1_MAX_STAGE: () => V1_MAX_STAGE,
49
57
  acceptanceVerdictSchema: () => acceptanceVerdictSchema,
58
+ aggregatePrecedent: () => aggregatePrecedent,
50
59
  applyBudgetClamp: () => applyBudgetClamp,
51
60
  baseTier: () => baseTier,
52
61
  blastRadiusVeto: () => blastRadiusVeto,
@@ -54,6 +63,7 @@ __export(index_exports, {
54
63
  buildSpecializationProfile: () => buildSpecializationProfile,
55
64
  buildUserPrompt: () => buildUserPrompt2,
56
65
  classify: () => classify,
66
+ compareToPrediction: () => compareToPrediction,
57
67
  computeExpertiseLevel: () => computeExpertiseLevel,
58
68
  computeHistoricalComplexity: () => computeHistoricalComplexity,
59
69
  computePersonaEffectiveness: () => computePersonaEffectiveness,
@@ -62,11 +72,14 @@ __export(index_exports, {
62
72
  computeStructuralComplexity: () => computeStructuralComplexity,
63
73
  createCanaryAdapter: () => createCanaryAdapter,
64
74
  decayWeight: () => decayWeight,
75
+ depthForLevel: () => depthForLevel,
65
76
  deriveAcceptanceAuthority: () => deriveAcceptanceAuthority,
66
77
  deriveAuthority: () => deriveAuthority,
67
78
  deriveRequiredTier: () => deriveRequiredTier,
68
79
  detectBlindSpots: () => detectBlindSpots,
80
+ dispatchableShapeKey: () => dispatchableShapeKey,
69
81
  enrich: () => enrich,
82
+ extractEntities: () => extractEntities,
70
83
  findingSchema: () => findingSchema,
71
84
  githubToRawWorkItem: () => githubToRawWorkItem,
72
85
  jiraToRawWorkItem: () => jiraToRawWorkItem,
@@ -74,16 +87,25 @@ __export(index_exports, {
74
87
  llmTiebreak: () => llmTiebreak,
75
88
  loadProfiles: () => loadProfiles,
76
89
  manualToRawWorkItem: () => manualToRawWorkItem,
90
+ pilotScore: () => pilotScore,
91
+ precedentLookupFromRecords: () => precedentLookupFromRecords,
92
+ rankTriageCandidates: () => rankTriageCandidates,
77
93
  recommendPersona: () => recommendPersona,
78
94
  refreshProfiles: () => refreshProfiles,
95
+ resolveGoNoGo: () => resolveGoNoGo,
96
+ resolveGoNoGoStaged: () => resolveGoNoGoStaged,
79
97
  resolveSection: () => resolveSection,
98
+ resolveStage: () => resolveStage,
99
+ runAutoBrainstorm: () => runAutoBrainstorm,
80
100
  runGraphOnlyChecks: () => runGraphOnlyChecks,
81
101
  runLlmSimulation: () => runLlmSimulation,
102
+ runScopingProbe: () => runScopingProbe,
82
103
  runStaticPass: () => runStaticPass,
83
104
  saveProfiles: () => saveProfiles,
84
105
  scoreCML: () => score,
85
106
  scoreToConcernSignals: () => scoreToConcernSignals,
86
107
  serializeSignals: () => serializeSignals,
108
+ shapeKey: () => shapeKey,
87
109
  temporalSuccessRate: () => temporalSuccessRate,
88
110
  toRawWorkItem: () => toRawWorkItem,
89
111
  verdictSchema: () => verdictSchema,
@@ -2344,16 +2366,394 @@ function deriveRequiredTier(complexity, risk, policy, spend, escalationFloor, sk
2344
2366
  const clamped = applyBudgetClamp(base, risk, policy, spend);
2345
2367
  return tierAtRank(Math.max(TIER_RANK[escalationFloor], TIER_RANK[clamped]));
2346
2368
  }
2369
+
2370
+ // src/triage/record.ts
2371
+ function shapeKey(labels, category, level) {
2372
+ const sortedLabels = Array.from(
2373
+ new Set(labels.map((l) => l.trim().replace(/[,|]/g, "")).filter((l) => l.length > 0))
2374
+ ).sort();
2375
+ return `${sortedLabels.join(",")}|${category}|${level}`;
2376
+ }
2377
+ function dispatchableShapeKey(labels, level) {
2378
+ return shapeKey(labels, "dispatchable", level);
2379
+ }
2380
+
2381
+ // src/triage/precedent.ts
2382
+ function aggregatePrecedent(records, shapeKey2) {
2383
+ let matched = 0;
2384
+ let total = 0;
2385
+ for (const rec of records) {
2386
+ if (rec.shapeKey !== shapeKey2) continue;
2387
+ if (!rec.outcome) continue;
2388
+ total += 1;
2389
+ if (rec.outcome.matched) matched += 1;
2390
+ }
2391
+ if (total === 0) return { kind: "unknown" };
2392
+ return { kind: "rate", matched, total, rate: matched / total };
2393
+ }
2394
+ function precedentLookupFromRecords(records) {
2395
+ return {
2396
+ rateForShape: (shapeKey2) => aggregatePrecedent(records, shapeKey2)
2397
+ };
2398
+ }
2399
+
2400
+ // src/triage/entities.ts
2401
+ var BACKTICKED_RE = /`([^`]+)`/g;
2402
+ var PATH_RE = /(?:\.\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_.-]+/g;
2403
+ var CAMEL_RE = /\b([A-Z][a-z]+[A-Za-z0-9]*[A-Z][A-Za-z0-9]*|[a-z]+[A-Z][A-Za-z0-9]*)\b/g;
2404
+ var DOTTED_RE = /\b[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)+\b/g;
2405
+ function extractEntities(text) {
2406
+ if (typeof text !== "string") return [];
2407
+ const trimmed = text.trim();
2408
+ if (trimmed.length === 0) return [];
2409
+ const seen = /* @__PURE__ */ new Set();
2410
+ const result = [];
2411
+ const add = (raw) => {
2412
+ const token = raw.trim();
2413
+ if (token.length === 0) return;
2414
+ if (seen.has(token)) return;
2415
+ seen.add(token);
2416
+ result.push(token);
2417
+ };
2418
+ for (const m of trimmed.matchAll(BACKTICKED_RE)) {
2419
+ const inner = m[1];
2420
+ if (inner !== void 0) add(inner);
2421
+ }
2422
+ for (const m of trimmed.matchAll(PATH_RE)) add(m[0]);
2423
+ for (const m of trimmed.matchAll(CAMEL_RE)) add(m[0]);
2424
+ for (const m of trimmed.matchAll(DOTTED_RE)) add(m[0]);
2425
+ return result;
2426
+ }
2427
+
2428
+ // src/triage/probe.ts
2429
+ var import_zod7 = require("zod");
2430
+ var DEFAULT_CONFIG = {
2431
+ boundedScopeMax: 40,
2432
+ dispatchConfidence: "medium",
2433
+ precedentBlockRate: 0,
2434
+ precedentMinSample: 1
2435
+ };
2436
+ var OpenDecisionsSchema = import_zod7.z.object({
2437
+ openDecisions: import_zod7.z.array(import_zod7.z.object({ question: import_zod7.z.string() })).describe(
2438
+ "Choices requiring human judgment (API shape, product tradeoff, irreversible action)"
2439
+ )
2440
+ });
2441
+ var OPEN_DECISIONS_SYSTEM_PROMPT = "You are triaging a backlog item for autonomous execution. Identify ONLY choices that genuinely require human judgment before an agent could safely proceed \u2014 API/interface shape, product tradeoffs, or irreversible/outward-facing actions. If the item is fully scoped and an agent could proceed without a human decision, return an empty array. Do not invent decisions; be conservative about what truly needs a human.";
2442
+ async function runScopingProbe(input, deps = {}) {
2443
+ const config = { ...DEFAULT_CONFIG, ...deps.config };
2444
+ const scope = await runScopeLever(input, deps.graph);
2445
+ const semanticRead = await runSemanticReadLever(input, scope.value, deps);
2446
+ const openDecisions = await runOpenDecisionsLever(input, deps.provider);
2447
+ const precedent = runPrecedentLever(input, semanticRead.value, deps.precedent);
2448
+ const levers = { scope, semanticRead, openDecisions, precedent };
2449
+ const verdict = semanticRead.value === "unknown" ? { level: "moderate", confidence: "low", signals: {}, source: "static" } : semanticRead.value;
2450
+ const { dispatchable, holdReason } = gate(levers, config);
2451
+ const rationale = buildRationale(levers, dispatchable, holdReason);
2452
+ return {
2453
+ externalId: input.externalId,
2454
+ verdict,
2455
+ dispatchable,
2456
+ ...holdReason !== void 0 ? { holdReason } : {},
2457
+ levers,
2458
+ rationale
2459
+ };
2460
+ }
2461
+ async function runScopeLever(input, graph) {
2462
+ if (graph === void 0) {
2463
+ return { value: "unknown", reason: "scope: no graph seam available" };
2464
+ }
2465
+ try {
2466
+ const resolved = [];
2467
+ for (const candidate of input.entityCandidates) {
2468
+ const hit = await graph.resolve(candidate);
2469
+ if (hit) resolved.push(hit);
2470
+ }
2471
+ const blastRadius = resolved.reduce((max, r) => Math.max(max, r.blastRadius), 0);
2472
+ const estimate = {
2473
+ candidates: input.entityCandidates,
2474
+ resolved,
2475
+ blastRadius,
2476
+ layersTouched: Math.min(resolved.length, 4),
2477
+ filesTouched: resolved.length
2478
+ };
2479
+ const note = resolved.length === 0 ? "scope: no entity resolved in graph (unresolved-scope)" : `scope: ${resolved.length} entity(ies) resolved, blastRadius ${blastRadius}`;
2480
+ return { value: estimate, reason: note };
2481
+ } catch (err) {
2482
+ return { value: "unknown", reason: `scope: graph lookup failed \u2014 ${errMsg(err)}` };
2483
+ }
2484
+ }
2485
+ async function runSemanticReadLever(input, scope, deps) {
2486
+ try {
2487
+ const signals = {
2488
+ descriptionLength: input.taskText.descriptionLength,
2489
+ specExists: input.taskText.specExists,
2490
+ acceptanceMeasurable: input.taskText.acceptanceMeasurable,
2491
+ ...scope !== "unknown" && scope.resolved.length > 0 ? {
2492
+ filesTouched: scope.filesTouched,
2493
+ layersTouched: scope.layersTouched,
2494
+ blastRadius: scope.blastRadius
2495
+ } : {}
2496
+ };
2497
+ const phase = scope !== "unknown" && scope.resolved.length > 0 ? "post-diff" : "pre-diff";
2498
+ const classifyInput = {
2499
+ signals,
2500
+ phase,
2501
+ riskHigh: input.riskHigh === true,
2502
+ prompt: input.taskText.prompt
2503
+ };
2504
+ const verdict = await classify(classifyInput, deps.provider, deps.models);
2505
+ return { value: verdict, reason: `semantic-read: ${verdict.level}/${verdict.confidence}` };
2506
+ } catch (err) {
2507
+ return { value: "unknown", reason: `semantic-read: classify failed \u2014 ${errMsg(err)}` };
2508
+ }
2509
+ }
2510
+ async function runOpenDecisionsLever(input, provider) {
2511
+ if (provider === void 0) {
2512
+ return { value: "unknown", reason: "open-decisions: no provider (offline)" };
2513
+ }
2514
+ try {
2515
+ const { result } = await provider.analyze({
2516
+ prompt: input.taskText.prompt,
2517
+ systemPrompt: OPEN_DECISIONS_SYSTEM_PROMPT,
2518
+ responseSchema: OpenDecisionsSchema,
2519
+ maxTokens: 512
2520
+ });
2521
+ const decisions = result.openDecisions ?? [];
2522
+ const note = decisions.length === 0 ? "open-decisions: none surfaced" : `open-decisions: ${decisions.length} requiring human judgment`;
2523
+ return { value: decisions, reason: note };
2524
+ } catch (err) {
2525
+ return { value: "unknown", reason: `open-decisions: assessment failed \u2014 ${errMsg(err)}` };
2526
+ }
2527
+ }
2528
+ function runPrecedentLever(input, verdict, precedent) {
2529
+ if (precedent === void 0) {
2530
+ return { value: "unknown", reason: "precedent: no store (cold-start)" };
2531
+ }
2532
+ try {
2533
+ const level = verdict === "unknown" ? "moderate" : verdict.level;
2534
+ const key = dispatchableShapeKey(input.labels, level);
2535
+ const rate = precedent.rateForShape(key);
2536
+ const note = rate.kind === "unknown" ? "precedent: unknown for this shape (no graded records)" : `precedent: ${rate.matched}/${rate.total} (${(rate.rate * 100).toFixed(0)}%)`;
2537
+ return { value: rate, reason: note };
2538
+ } catch (err) {
2539
+ return { value: "unknown", reason: `precedent: lookup failed \u2014 ${errMsg(err)}` };
2540
+ }
2541
+ }
2542
+ function gate(levers, config) {
2543
+ const scope = levers.scope.value;
2544
+ if (scope === "unknown" || scope.resolved.length === 0) {
2545
+ return { dispatchable: false, holdReason: "unresolved-scope" };
2546
+ }
2547
+ if (scope.blastRadius > config.boundedScopeMax) {
2548
+ return { dispatchable: false, holdReason: "unresolved-scope" };
2549
+ }
2550
+ const read = levers.semanticRead.value;
2551
+ if (read === "unknown") {
2552
+ return { dispatchable: false, holdReason: "not-in-band" };
2553
+ }
2554
+ const inBand = read.level === "trivial" || read.level === "simple";
2555
+ const confidentEnough = CONFIDENCE_RANK[read.confidence] >= CONFIDENCE_RANK[config.dispatchConfidence];
2556
+ if (!inBand || !confidentEnough) {
2557
+ return { dispatchable: false, holdReason: "not-in-band" };
2558
+ }
2559
+ const decisions = levers.openDecisions.value;
2560
+ if (decisions === "unknown") {
2561
+ return { dispatchable: false, holdReason: "read-incomplete" };
2562
+ }
2563
+ if (decisions.length > 0) {
2564
+ return { dispatchable: false, holdReason: "open-decision" };
2565
+ }
2566
+ const precedent = levers.precedent.value;
2567
+ if (precedent !== "unknown" && precedent.kind === "rate" && precedent.total >= (config.precedentMinSample ?? 1) && precedent.rate <= (config.precedentBlockRate ?? 0)) {
2568
+ return { dispatchable: false, holdReason: "precedent-contradicts" };
2569
+ }
2570
+ return { dispatchable: true };
2571
+ }
2572
+ function buildRationale(levers, dispatchable, holdReason) {
2573
+ const parts = [];
2574
+ for (const lever of [levers.scope, levers.semanticRead, levers.openDecisions, levers.precedent]) {
2575
+ if (lever.reason) parts.push(lever.reason);
2576
+ }
2577
+ const decision = dispatchable ? "DISPATCHABLE \u2014 all levers corroborate." : `HELD (${holdReason}).`;
2578
+ return `${decision} ${parts.join("; ")}`;
2579
+ }
2580
+ function errMsg(err) {
2581
+ return err instanceof Error ? err.message : String(err);
2582
+ }
2583
+
2584
+ // src/triage/rank.ts
2585
+ function pilotScore(c) {
2586
+ const effort = c.effort > 0 ? c.effort : 1e-6;
2587
+ const score2 = c.impact * c.confidence / effort;
2588
+ return Number.isFinite(score2) ? score2 : 0;
2589
+ }
2590
+ function rankTriageCandidates(candidates) {
2591
+ return [...candidates].sort((a, b) => {
2592
+ const sa = pilotScore(a);
2593
+ const sb = pilotScore(b);
2594
+ if (sa !== sb) return sb - sa;
2595
+ if (a.impact !== b.impact) return b.impact - a.impact;
2596
+ return a.externalId < b.externalId ? -1 : a.externalId > b.externalId ? 1 : 0;
2597
+ });
2598
+ }
2599
+
2600
+ // src/triage/brainstorm/types.ts
2601
+ var DEPTH_BY_LEVEL = {
2602
+ trivial: { maxForks: 2 },
2603
+ simple: { maxForks: 4 },
2604
+ // moderate/complex are OUT of the eligible band (the probe holds them to human) — a depth
2605
+ // is defined only so the mapping is total; the brainstorm should never run on them.
2606
+ moderate: { maxForks: 4 },
2607
+ complex: { maxForks: 4 }
2608
+ };
2609
+ function depthForLevel(level) {
2610
+ return DEPTH_BY_LEVEL[level] ?? { maxForks: 2 };
2611
+ }
2612
+
2613
+ // src/triage/brainstorm/runner.ts
2614
+ async function runAutoBrainstorm(input, generator, depth) {
2615
+ const accepted = [];
2616
+ const ceiling = Math.max(0, depth.maxForks);
2617
+ for (let index = 0; index < ceiling; index++) {
2618
+ let decision;
2619
+ try {
2620
+ decision = await generator.next(index, accepted);
2621
+ } catch (err) {
2622
+ return {
2623
+ kind: "halted",
2624
+ fork: { id: `fork-${index}`, question: "brainstorm errored before deciding", options: [] },
2625
+ reason: "error",
2626
+ detail: errMsg2(err)
2627
+ };
2628
+ }
2629
+ if (decision === null || decision === void 0) break;
2630
+ if (decision.confidence !== "high") {
2631
+ return {
2632
+ kind: "halted",
2633
+ fork: decision.fork,
2634
+ reason: "low-confidence",
2635
+ detail: `fork '${decision.fork.id}' recommended '${decision.recommendation}' at confidence '${decision.confidence}' (below the 'high' bar) \u2014 ${decision.rationale}`
2636
+ };
2637
+ }
2638
+ accepted.push(decision);
2639
+ }
2640
+ const spec = {
2641
+ externalId: input.externalId,
2642
+ title: input.title,
2643
+ summary: input.summary,
2644
+ decisions: accepted
2645
+ };
2646
+ return { kind: "completed", spec };
2647
+ }
2648
+ function errMsg2(err) {
2649
+ return err instanceof Error ? err.message : String(err);
2650
+ }
2651
+
2652
+ // src/triage/retrospective.ts
2653
+ var LEVEL_RANK = {
2654
+ trivial: 0,
2655
+ simple: 1,
2656
+ moderate: 2,
2657
+ complex: 3
2658
+ };
2659
+ var BLAST_TOLERANCE_FACTOR = 1.5;
2660
+ var BLAST_TOLERANCE_ABS = 2;
2661
+ var DEFAULT_RETROSPECTIVE_CONFIG = { exceededByBands: 1 };
2662
+ function blockEscalate(exceededBy = 1) {
2663
+ return { matched: false, exceededBy: Math.max(1, exceededBy), action: "block-escalate" };
2664
+ }
2665
+ function isLevel(value) {
2666
+ return typeof value === "string" && Object.prototype.hasOwnProperty.call(LEVEL_RANK, value);
2667
+ }
2668
+ function blastRadiusOf(verdict) {
2669
+ const raw = verdict.signals?.blastRadius;
2670
+ return typeof raw === "number" && Number.isFinite(raw) ? raw : void 0;
2671
+ }
2672
+ function compareToPrediction(prediction, postDiffVerdict, config = DEFAULT_RETROSPECTIVE_CONFIG) {
2673
+ if (prediction == null || postDiffVerdict == null) return blockEscalate();
2674
+ const predictedLevel = prediction.verdict?.level;
2675
+ const actualLevel = postDiffVerdict.level;
2676
+ if (!isLevel(predictedLevel) || !isLevel(actualLevel)) return blockEscalate();
2677
+ const levelDelta = LEVEL_RANK[actualLevel] - LEVEL_RANK[predictedLevel];
2678
+ const bandThreshold = Math.max(1, Math.floor(config.exceededByBands));
2679
+ if (levelDelta >= bandThreshold) return blockEscalate(levelDelta);
2680
+ const predictedScope = typeof prediction.scopeEstimate === "number" && Number.isFinite(prediction.scopeEstimate) ? prediction.scopeEstimate : 0;
2681
+ const actualBlast = blastRadiusOf(postDiffVerdict);
2682
+ if (actualBlast !== void 0) {
2683
+ const threshold = predictedScope * BLAST_TOLERANCE_FACTOR + BLAST_TOLERANCE_ABS;
2684
+ if (actualBlast > threshold) return blockEscalate();
2685
+ }
2686
+ return { matched: true, exceededBy: 0, action: "verify" };
2687
+ }
2688
+
2689
+ // src/triage/ratchet.ts
2690
+ var V1_MAX_STAGE = 2;
2691
+ var DEFAULT_RATCHET_CONFIG = {
2692
+ threshold: 0.9,
2693
+ minSample: 5,
2694
+ window: 10
2695
+ };
2696
+ function resolveStage(history, config = DEFAULT_RATCHET_CONFIG) {
2697
+ const window = Math.max(1, Math.floor(config.window));
2698
+ const ordered = history.length > 1 ? [...history].sort((a, b) => (a.ts ?? "").localeCompare(b.ts ?? "")) : history;
2699
+ const recent = ordered.slice(-window);
2700
+ if (recent.length < config.minSample) return 1;
2701
+ if (recent[recent.length - 1]?.matched === false) return 1;
2702
+ const matched = recent.reduce((n, o) => o.matched ? n + 1 : n, 0);
2703
+ const rate = matched / recent.length;
2704
+ if (rate < config.threshold) return 1;
2705
+ return Math.min(2, V1_MAX_STAGE);
2706
+ }
2707
+
2708
+ // src/triage/gate.ts
2709
+ var AUTO_EXECUTE_CATEGORIES = /* @__PURE__ */ new Set([
2710
+ "quick-fix",
2711
+ "diagnostic"
2712
+ ]);
2713
+ function resolveGoNoGoStaged(candidates) {
2714
+ const approved = [];
2715
+ const held = [];
2716
+ for (const c of candidates) {
2717
+ if (c.effectiveStage !== 1 && c.effectiveStage !== 2) {
2718
+ held.push({
2719
+ externalId: c.externalId,
2720
+ category: c.category,
2721
+ reason: "ratchet-stage-unsupported"
2722
+ });
2723
+ continue;
2724
+ }
2725
+ if (!AUTO_EXECUTE_CATEGORIES.has(c.category)) {
2726
+ held.push({ externalId: c.externalId, category: c.category, reason: "not-auto-executable" });
2727
+ continue;
2728
+ }
2729
+ if (!c.humanApproved) {
2730
+ held.push({ externalId: c.externalId, category: c.category, reason: "awaiting-human-go" });
2731
+ continue;
2732
+ }
2733
+ approved.push({ ...c, effectiveStage: c.effectiveStage });
2734
+ }
2735
+ return { approved, held };
2736
+ }
2737
+ function resolveGoNoGo(candidates, stage) {
2738
+ return resolveGoNoGoStaged(candidates.map((c) => ({ ...c, effectiveStage: stage })));
2739
+ }
2347
2740
  // Annotate the CommonJS export names for ESM import in node:
2348
2741
  0 && (module.exports = {
2349
2742
  ACCEPTANCE_EVAL_SYSTEM_PROMPT,
2743
+ AUTO_EXECUTE_CATEGORIES,
2350
2744
  AcceptanceEvaluator,
2351
2745
  AnthropicAnalysisProvider,
2746
+ BLAST_TOLERANCE_ABS,
2747
+ BLAST_TOLERANCE_FACTOR,
2352
2748
  ClaudeCliAnalysisProvider,
2353
2749
  DEFAULT_DEGRADE_AT_PCT,
2750
+ DEFAULT_RATCHET_CONFIG,
2751
+ DEFAULT_RETROSPECTIVE_CONFIG,
2752
+ DEPTH_BY_LEVEL,
2354
2753
  ExecutionOutcomeConnector,
2355
2754
  GraphValidator,
2356
2755
  IntelligencePipeline,
2756
+ LEVEL_RANK,
2357
2757
  OUTCOME_EVAL_SYSTEM_PROMPT,
2358
2758
  OpenAICompatibleAnalysisProvider,
2359
2759
  OutcomeEvaluator,
@@ -2362,7 +2762,9 @@ function deriveRequiredTier(complexity, risk, policy, spend, escalationFloor, sk
2362
2762
  SENSITIVE_BLAST_THRESHOLD,
2363
2763
  STATIC_WEIGHTS,
2364
2764
  TIER_RANK,
2765
+ V1_MAX_STAGE,
2365
2766
  acceptanceVerdictSchema,
2767
+ aggregatePrecedent,
2366
2768
  applyBudgetClamp,
2367
2769
  baseTier,
2368
2770
  blastRadiusVeto,
@@ -2370,6 +2772,7 @@ function deriveRequiredTier(complexity, risk, policy, spend, escalationFloor, sk
2370
2772
  buildSpecializationProfile,
2371
2773
  buildUserPrompt,
2372
2774
  classify,
2775
+ compareToPrediction,
2373
2776
  computeExpertiseLevel,
2374
2777
  computeHistoricalComplexity,
2375
2778
  computePersonaEffectiveness,
@@ -2378,11 +2781,14 @@ function deriveRequiredTier(complexity, risk, policy, spend, escalationFloor, sk
2378
2781
  computeStructuralComplexity,
2379
2782
  createCanaryAdapter,
2380
2783
  decayWeight,
2784
+ depthForLevel,
2381
2785
  deriveAcceptanceAuthority,
2382
2786
  deriveAuthority,
2383
2787
  deriveRequiredTier,
2384
2788
  detectBlindSpots,
2789
+ dispatchableShapeKey,
2385
2790
  enrich,
2791
+ extractEntities,
2386
2792
  findingSchema,
2387
2793
  githubToRawWorkItem,
2388
2794
  jiraToRawWorkItem,
@@ -2390,16 +2796,25 @@ function deriveRequiredTier(complexity, risk, policy, spend, escalationFloor, sk
2390
2796
  llmTiebreak,
2391
2797
  loadProfiles,
2392
2798
  manualToRawWorkItem,
2799
+ pilotScore,
2800
+ precedentLookupFromRecords,
2801
+ rankTriageCandidates,
2393
2802
  recommendPersona,
2394
2803
  refreshProfiles,
2804
+ resolveGoNoGo,
2805
+ resolveGoNoGoStaged,
2395
2806
  resolveSection,
2807
+ resolveStage,
2808
+ runAutoBrainstorm,
2396
2809
  runGraphOnlyChecks,
2397
2810
  runLlmSimulation,
2811
+ runScopingProbe,
2398
2812
  runStaticPass,
2399
2813
  saveProfiles,
2400
2814
  scoreCML,
2401
2815
  scoreToConcernSignals,
2402
2816
  serializeSignals,
2817
+ shapeKey,
2403
2818
  temporalSuccessRate,
2404
2819
  toRawWorkItem,
2405
2820
  verdictSchema,