@resolveio/server-lib 22.3.187 → 22.3.189

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@resolveio/server-lib",
3
- "version": "22.3.187",
3
+ "version": "22.3.189",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "package": "./build_package.sh",
@@ -67,7 +67,43 @@ export interface AssistantAnswerQualityDecision {
67
67
  failedChecks: string[];
68
68
  recordedAt: string;
69
69
  }
70
+ export type AssistantAnswerActionabilityStatus = 'ready_to_answer' | 'needs_query_repair' | 'needs_permission' | 'needs_no_data_verification' | 'needs_date_window_repair' | 'needs_query_shape_repair' | 'needs_evidence' | 'needs_confidence_review' | 'needs_next_action' | 'incorrect' | 'blocked';
71
+ export interface AssistantAnswerActionabilityContract {
72
+ contractId: string;
73
+ status: AssistantAnswerActionabilityStatus;
74
+ primaryCommand: string;
75
+ label: string;
76
+ canAnswerCustomer: boolean;
77
+ canDraftSupportReply: boolean;
78
+ canSendCustomerReply: boolean;
79
+ requiresHumanReview: boolean;
80
+ canRunWithoutCodexMonitor: boolean;
81
+ codexFallbackRequired: boolean;
82
+ costRisk: 'free_or_deterministic' | 'small_model_or_qa' | 'expensive_model' | 'release_or_customer_send' | 'manual_blocked';
83
+ queryResultClass: AssistantAnswerQualityDecision['queryStatus'];
84
+ confidenceLevel: AssistantAnswerQualityDecision['confidenceLevel'];
85
+ decisionBasis: {
86
+ answerQualityStatus: AssistantAnswerQualityStatus;
87
+ queryStatus: AssistantAnswerQualityDecision['queryStatus'];
88
+ queryEvidencePresent: boolean;
89
+ noDataConfirmed: boolean;
90
+ legalQueryShape: boolean;
91
+ dateWindowRequired: boolean;
92
+ dateWindowPresent: boolean;
93
+ citationCount: number;
94
+ nextActionCount: number;
95
+ };
96
+ requiredEvidence: string[];
97
+ successEvidence: string[];
98
+ blockers: string[];
99
+ nextActions: string[];
100
+ nextCommands: string[];
101
+ forbiddenActions: string[];
102
+ evidenceRefs: string[];
103
+ recordedAt: string;
104
+ }
70
105
  export declare function evaluateAssistantAnswerQuality(input?: AssistantAnswerQualityInput): AssistantAnswerQualityDecision;
106
+ export declare function buildAssistantAnswerActionabilityContract(decision: AssistantAnswerQualityDecision, now?: Date | string): AssistantAnswerActionabilityContract;
71
107
  export declare function buildSupportAIRunFromEvidence(input: SupportAIRunAdapterInput): AIRun;
72
108
  export declare function buildAICoderAIRunFromEvidence(input: AICoderAIRunAdapterInput): AIRun;
73
109
  export declare function buildAssistantAIRunFromEvidence(input: AssistantAIRunAdapterInput): AIRun;
@@ -48,6 +48,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
48
48
  };
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
50
  exports.evaluateAssistantAnswerQuality = evaluateAssistantAnswerQuality;
51
+ exports.buildAssistantAnswerActionabilityContract = buildAssistantAnswerActionabilityContract;
51
52
  exports.buildSupportAIRunFromEvidence = buildSupportAIRunFromEvidence;
52
53
  exports.buildAICoderAIRunFromEvidence = buildAICoderAIRunFromEvidence;
53
54
  exports.buildAssistantAIRunFromEvidence = buildAssistantAIRunFromEvidence;
@@ -2299,7 +2300,7 @@ function aicoderNextActionContractObject(app, job, evidence) {
2299
2300
  return evidenceObject(continuationDecision.nextActionContract, continuationDecision.next_action_contract, job.nextActionContract, job.next_action_contract, job.aicoderNextActionContract, job.aicoder_next_action_contract, job.aiCoderNextActionContract, job.ai_coder_next_action_contract, app.nextActionContract, app.next_action_contract, evidence.nextActionContract, evidence.next_action_contract, evidence.aicoderNextActionContract, evidence.aicoder_next_action_contract);
2300
2301
  }
2301
2302
  function aicoderNextActionContractGate(contract, now) {
2302
- var _a, _b, _c, _d, _e;
2303
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
2303
2304
  if (!contract || !Object.keys(contract).length) {
2304
2305
  return undefined;
2305
2306
  }
@@ -2339,10 +2340,13 @@ function aicoderNextActionContractGate(contract, now) {
2339
2340
  codexFallbackReason: cleanText(contract.codexFallbackReason || contract.codex_fallback_reason, 1000),
2340
2341
  costRisk: cleanText(contract.costRisk || contract.cost_risk, 120),
2341
2342
  workflowFirstSatisfied: booleanFlag((_e = contract.workflowFirstSatisfied) !== null && _e !== void 0 ? _e : contract.workflow_first_satisfied) === true,
2343
+ hotfixCommitRequired: booleanFlag((_h = (_g = (_f = contract.hotfixCommitRequired) !== null && _f !== void 0 ? _f : contract.hotfix_commit_required) !== null && _g !== void 0 ? _g : plainObject(contract.decisionBasis || contract.decision_basis).hotfixCommitRequired) !== null && _h !== void 0 ? _h : plainObject(contract.decisionBasis || contract.decision_basis).hotfix_commit_required) === true,
2344
+ liveHotfixBlockedUntilCommit: booleanFlag((_l = (_k = (_j = contract.liveHotfixBlockedUntilCommit) !== null && _j !== void 0 ? _j : contract.live_hotfix_blocked_until_commit) !== null && _k !== void 0 ? _k : plainObject(contract.decisionBasis || contract.decision_basis).liveHotfixBlockedUntilCommit) !== null && _l !== void 0 ? _l : plainObject(contract.decisionBasis || contract.decision_basis).live_hotfix_blocked_until_commit) === true,
2342
2345
  decisionBasis: plainObject(contract.decisionBasis || contract.decision_basis),
2343
2346
  preconditions: cleanStringList(contract.preconditions, 40, 500),
2344
2347
  expectedStateTransition: cleanText(contract.expectedStateTransition || contract.expected_state_transition, 1000),
2345
2348
  successEvidence: cleanStringList(contract.successEvidence || contract.success_evidence, 40, 500),
2349
+ requiredHotfixCommitProof: cleanStringList(contract.requiredHotfixCommitProof || contract.required_hotfix_commit_proof, 20, 240),
2346
2350
  stopConditions: cleanStringList(contract.stopConditions || contract.stop_conditions, 40, 500),
2347
2351
  forbiddenActions: cleanStringList(contract.forbiddenActions || contract.forbidden_actions, 40, 500),
2348
2352
  nextCommands: cleanStringList(contract.nextCommands || contract.next_commands, 40, 240),
@@ -2711,6 +2715,185 @@ function assistantAnswerQualityGate(decision, now) {
2711
2715
  }
2712
2716
  };
2713
2717
  }
2718
+ function assistantActionabilityStatus(decision) {
2719
+ switch (decision.status) {
2720
+ case 'ready':
2721
+ return 'ready_to_answer';
2722
+ case 'query_error':
2723
+ return 'needs_query_repair';
2724
+ case 'permission_error':
2725
+ return 'needs_permission';
2726
+ case 'no_data_unverified':
2727
+ return 'needs_no_data_verification';
2728
+ case 'date_incorrect':
2729
+ case 'missing_date_window':
2730
+ return 'needs_date_window_repair';
2731
+ case 'illegal_query_shape':
2732
+ return 'needs_query_shape_repair';
2733
+ case 'missing_data_source':
2734
+ case 'missing_query_proof':
2735
+ case 'missing_citations':
2736
+ return 'needs_evidence';
2737
+ case 'low_confidence':
2738
+ return 'needs_confidence_review';
2739
+ case 'missing_next_action':
2740
+ return 'needs_next_action';
2741
+ case 'incorrect':
2742
+ return 'incorrect';
2743
+ default:
2744
+ return 'blocked';
2745
+ }
2746
+ }
2747
+ function assistantActionabilityCommand(status) {
2748
+ switch (status) {
2749
+ case 'ready_to_answer':
2750
+ return 'answer_from_verified_system_data';
2751
+ case 'needs_query_repair':
2752
+ return 'repair_assistant_query_and_rerun';
2753
+ case 'needs_permission':
2754
+ return 'request_assistant_data_permission';
2755
+ case 'needs_no_data_verification':
2756
+ return 'verify_no_data_with_scoped_probe';
2757
+ case 'needs_date_window_repair':
2758
+ return 'repair_assistant_date_window_and_rerun';
2759
+ case 'needs_query_shape_repair':
2760
+ return 'repair_assistant_mongo_query_shape';
2761
+ case 'needs_confidence_review':
2762
+ return 'review_assistant_confidence_evidence';
2763
+ case 'needs_next_action':
2764
+ return 'add_assistant_next_action';
2765
+ case 'incorrect':
2766
+ return 'repair_assistant_answer_from_failed_check';
2767
+ case 'needs_evidence':
2768
+ case 'blocked':
2769
+ default:
2770
+ return 'collect_assistant_answer_evidence';
2771
+ }
2772
+ }
2773
+ function assistantActionabilityLabel(status) {
2774
+ switch (status) {
2775
+ case 'ready_to_answer':
2776
+ return 'Answer From Verified Data';
2777
+ case 'needs_query_repair':
2778
+ return 'Repair Query';
2779
+ case 'needs_permission':
2780
+ return 'Request Data Permission';
2781
+ case 'needs_no_data_verification':
2782
+ return 'Verify No Data';
2783
+ case 'needs_date_window_repair':
2784
+ return 'Repair Date Window';
2785
+ case 'needs_query_shape_repair':
2786
+ return 'Repair Query Shape';
2787
+ case 'needs_confidence_review':
2788
+ return 'Review Confidence';
2789
+ case 'needs_next_action':
2790
+ return 'Add Next Action';
2791
+ case 'incorrect':
2792
+ return 'Repair Incorrect Answer';
2793
+ default:
2794
+ return 'Collect Answer Evidence';
2795
+ }
2796
+ }
2797
+ function buildAssistantAnswerActionabilityContract(decision, now) {
2798
+ var status = assistantActionabilityStatus(decision);
2799
+ var primaryCommand = assistantActionabilityCommand(status);
2800
+ var ready = status === 'ready_to_answer';
2801
+ var noDataReady = ready && decision.queryStatus === 'no_data' && decision.noDataConfirmed;
2802
+ var canAnswerCustomer = ready && (decision.queryStatus === 'ok'
2803
+ || noDataReady
2804
+ || decision.queryEvidenceRequired === false);
2805
+ var canDraftSupportReply = canAnswerCustomer && decision.confidenceLevel === 'high';
2806
+ var requiresHumanReview = !canAnswerCustomer || canDraftSupportReply;
2807
+ var cheapRepair = /needs_(?:no_data|date_window|query_shape|next_action)|needs_evidence/.test(status);
2808
+ var blockers = decision.blockers.length
2809
+ ? decision.blockers
2810
+ : (ready ? [] : [decision.reason]);
2811
+ var requiredEvidence = Array.from(new Set(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read((decision.queryEvidenceRequired ? ['structured query/tool execution proof'] : [])), false), __read((decision.dateWindowRequired ? ['concrete date-window start and end'] : [])), false), __read((decision.queryStatus === 'no_data' ? ['noDataConfirmed=true from scoped probe or query evidence'] : [])), false), __read((decision.legalQueryShape ? [] : ['legal Mongo query/projection shape'])), false), __read((decision.citationRefs.length || decision.evidenceRefs.length ? [] : ['citationRefs or evidenceRefs'])), false), __read((decision.nextActions.length ? [] : ['one explicit next action or no-action state'])), false), __read((decision.confidenceLevel === 'low' || decision.confidenceLevel === 'unknown' ? ['medium/high confidence evidence'] : [])), false))).slice(0, 20);
2812
+ return {
2813
+ contractId: "assistant-actionability:".concat(decision.status, ":").concat(decision.queryStatus, ":").concat(decision.recordedAt),
2814
+ status: status,
2815
+ primaryCommand: primaryCommand,
2816
+ label: assistantActionabilityLabel(status),
2817
+ canAnswerCustomer: canAnswerCustomer,
2818
+ canDraftSupportReply: canDraftSupportReply,
2819
+ canSendCustomerReply: false,
2820
+ requiresHumanReview: requiresHumanReview,
2821
+ canRunWithoutCodexMonitor: ready || cheapRepair,
2822
+ codexFallbackRequired: !ready && !cheapRepair,
2823
+ costRisk: ready
2824
+ ? 'free_or_deterministic'
2825
+ : status === 'needs_permission'
2826
+ ? 'manual_blocked'
2827
+ : (status === 'needs_query_repair' || status === 'incorrect' ? 'small_model_or_qa' : 'free_or_deterministic'),
2828
+ queryResultClass: decision.queryStatus,
2829
+ confidenceLevel: decision.confidenceLevel,
2830
+ decisionBasis: {
2831
+ answerQualityStatus: decision.status,
2832
+ queryStatus: decision.queryStatus,
2833
+ queryEvidencePresent: decision.queryEvidencePresent,
2834
+ noDataConfirmed: decision.noDataConfirmed,
2835
+ legalQueryShape: decision.legalQueryShape,
2836
+ dateWindowRequired: decision.dateWindowRequired,
2837
+ dateWindowPresent: decision.dateWindowPresent,
2838
+ citationCount: decision.citationRefs.length + decision.evidenceRefs.length,
2839
+ nextActionCount: decision.nextActions.length
2840
+ },
2841
+ requiredEvidence: requiredEvidence,
2842
+ successEvidence: Array.from(new Set(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read((ready ? ['assistant answer quality gate passed'] : [])), false), __read((decision.queryEvidenceRefs.length ? decision.queryEvidenceRefs : [])), false), __read((decision.citationRefs.length ? decision.citationRefs : [])), false), __read((decision.evidenceRefs.length ? decision.evidenceRefs : [])), false))).slice(0, 20),
2843
+ blockers: blockers,
2844
+ nextActions: decision.nextActions,
2845
+ nextCommands: Array.from(new Set(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([
2846
+ primaryCommand
2847
+ ], __read((status === 'needs_query_repair' ? ['fix_query_error', 'rerun_assistant_query'] : [])), false), __read((status === 'needs_no_data_verification' ? ['run_tiny_shape_probe', 'record_no_data_confirmed'] : [])), false), __read((status === 'needs_date_window_repair' ? ['resolve_current_date', 'record_concrete_date_window', 'rerun_assistant_query'] : [])), false), __read((status === 'needs_query_shape_repair' ? ['rewrite_illegal_projection', 'rerun_query_shape_validator'] : [])), false), __read((status === 'needs_permission' ? ['request_permission_or_choose_allowed_route'] : [])), false), [
2848
+ 'record_assistant_actionability_result'
2849
+ ], false))).slice(0, 20),
2850
+ forbiddenActions: Array.from(new Set(__spreadArray(__spreadArray(__spreadArray(__spreadArray([
2851
+ 'Do not answer from keyword or route guesses without verified query evidence.',
2852
+ 'Do not claim no data when queryStatus is query_error or permission_error.'
2853
+ ], __read((decision.queryStatus === 'no_data' && !decision.noDataConfirmed ? ['Do not present no-data answer until noDataConfirmed=true.'] : [])), false), __read((decision.legalQueryShape ? [] : ['Do not answer from illegal Mongo projection/query shape.'])), false), __read((decision.dateWindowRequired && !decision.dateWindowPresent ? ['Do not answer dated questions without concrete start/end date evidence.'] : [])), false), __read((decision.confidenceLevel === 'low' || decision.confidenceLevel === 'unknown' ? ['Do not draft support/customer reply from low or unknown confidence.'] : [])), false))).slice(0, 20),
2854
+ evidenceRefs: Array.from(new Set(__spreadArray(__spreadArray(__spreadArray([], __read(decision.queryEvidenceRefs), false), __read(decision.citationRefs), false), __read(decision.evidenceRefs), false))).slice(0, 40),
2855
+ recordedAt: isoNow(now || decision.recordedAt)
2856
+ };
2857
+ }
2858
+ function assistantAnswerActionabilityGate(contract, now) {
2859
+ var status = contract.status === 'ready_to_answer'
2860
+ ? 'pass'
2861
+ : contract.status === 'incorrect' || contract.status === 'needs_query_shape_repair' || contract.status === 'needs_date_window_repair'
2862
+ ? 'fail'
2863
+ : 'blocked';
2864
+ return {
2865
+ key: 'assistant_answer_actionability',
2866
+ label: 'Assistant answer actionability',
2867
+ status: status,
2868
+ reason: status === 'pass'
2869
+ ? 'Assistant answer can proceed from verified structured evidence.'
2870
+ : (contract.blockers.join(' ') || 'Assistant answer is blocked until actionability evidence is complete.'),
2871
+ evidenceRefs: contract.evidenceRefs,
2872
+ recordedAt: isoNow(now || contract.recordedAt),
2873
+ metadata: {
2874
+ contractId: contract.contractId,
2875
+ status: contract.status,
2876
+ primaryCommand: contract.primaryCommand,
2877
+ label: contract.label,
2878
+ canAnswerCustomer: contract.canAnswerCustomer,
2879
+ canDraftSupportReply: contract.canDraftSupportReply,
2880
+ canSendCustomerReply: contract.canSendCustomerReply,
2881
+ requiresHumanReview: contract.requiresHumanReview,
2882
+ canRunWithoutCodexMonitor: contract.canRunWithoutCodexMonitor,
2883
+ codexFallbackRequired: contract.codexFallbackRequired,
2884
+ costRisk: contract.costRisk,
2885
+ queryResultClass: contract.queryResultClass,
2886
+ confidenceLevel: contract.confidenceLevel,
2887
+ decisionBasis: contract.decisionBasis,
2888
+ requiredEvidence: contract.requiredEvidence,
2889
+ successEvidence: contract.successEvidence,
2890
+ blockers: contract.blockers,
2891
+ nextActions: contract.nextActions,
2892
+ nextCommands: contract.nextCommands,
2893
+ forbiddenActions: contract.forbiddenActions
2894
+ }
2895
+ };
2896
+ }
2714
2897
  function applyAssistantAnswerQualityGate(qa, decision, now) {
2715
2898
  var gate = assistantAnswerQualityGate(decision, now);
2716
2899
  if (decision.ready) {
@@ -3068,7 +3251,7 @@ function buildSupportAIRunFromEvidence(input) {
3068
3251
  }
3069
3252
  function buildAICoderAIRunFromEvidence(input) {
3070
3253
  var e_30, _a;
3071
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25;
3254
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28;
3072
3255
  var app = input.app || {};
3073
3256
  var job = input.job || {};
3074
3257
  var evidence = buildAICoderQaEvidence(input);
@@ -3079,8 +3262,8 @@ function buildAICoderAIRunFromEvidence(input) {
3079
3262
  addSourceId(sourceIds, 'jobId', job._id || job.id || job.jobId);
3080
3263
  addSourceId(sourceIds, 'domain', app.domain || app.customDomain || job.domain);
3081
3264
  try {
3082
- for (var _26 = __values(asArray(input.logs)), _27 = _26.next(); !_27.done; _27 = _26.next()) {
3083
- var log = _27.value;
3265
+ for (var _29 = __values(asArray(input.logs)), _30 = _29.next(); !_30.done; _30 = _29.next()) {
3266
+ var log = _30.value;
3084
3267
  pushEvent(events, {
3085
3268
  type: log.type === 'scorecard' ? 'scorecard' : 'log',
3086
3269
  category: cleanText(log.category || log.phase || log.level, 160),
@@ -3098,7 +3281,7 @@ function buildAICoderAIRunFromEvidence(input) {
3098
3281
  catch (e_30_1) { e_30 = { error: e_30_1 }; }
3099
3282
  finally {
3100
3283
  try {
3101
- if (_27 && !_27.done && (_a = _26.return)) _a.call(_26);
3284
+ if (_30 && !_30.done && (_a = _29.return)) _a.call(_29);
3102
3285
  }
3103
3286
  finally { if (e_30) throw e_30.error; }
3104
3287
  }
@@ -3293,13 +3476,16 @@ function buildAICoderAIRunFromEvidence(input) {
3293
3476
  codexFallbackRequired: ((_16 = nextActionContractGate.metadata) === null || _16 === void 0 ? void 0 : _16.codexFallbackRequired) === true,
3294
3477
  costRisk: cleanText((_17 = nextActionContractGate.metadata) === null || _17 === void 0 ? void 0 : _17.costRisk, 120),
3295
3478
  workflowFirstSatisfied: ((_18 = nextActionContractGate.metadata) === null || _18 === void 0 ? void 0 : _18.workflowFirstSatisfied) === true,
3296
- decisionBasis: plainObject((_19 = nextActionContractGate.metadata) === null || _19 === void 0 ? void 0 : _19.decisionBasis),
3297
- preconditions: cleanStringList((_20 = nextActionContractGate.metadata) === null || _20 === void 0 ? void 0 : _20.preconditions, 20, 500),
3298
- successEvidence: cleanStringList((_21 = nextActionContractGate.metadata) === null || _21 === void 0 ? void 0 : _21.successEvidence, 20, 500),
3299
- stopConditions: cleanStringList((_22 = nextActionContractGate.metadata) === null || _22 === void 0 ? void 0 : _22.stopConditions, 20, 500),
3300
- forbiddenActions: cleanStringList((_23 = nextActionContractGate.metadata) === null || _23 === void 0 ? void 0 : _23.forbiddenActions, 20, 500),
3301
- nextCommands: cleanStringList((_24 = nextActionContractGate.metadata) === null || _24 === void 0 ? void 0 : _24.nextCommands, 20, 240),
3302
- blockers: cleanStringList((_25 = nextActionContractGate.metadata) === null || _25 === void 0 ? void 0 : _25.blockers, 20, 500)
3479
+ hotfixCommitRequired: ((_19 = nextActionContractGate.metadata) === null || _19 === void 0 ? void 0 : _19.hotfixCommitRequired) === true,
3480
+ liveHotfixBlockedUntilCommit: ((_20 = nextActionContractGate.metadata) === null || _20 === void 0 ? void 0 : _20.liveHotfixBlockedUntilCommit) === true,
3481
+ decisionBasis: plainObject((_21 = nextActionContractGate.metadata) === null || _21 === void 0 ? void 0 : _21.decisionBasis),
3482
+ preconditions: cleanStringList((_22 = nextActionContractGate.metadata) === null || _22 === void 0 ? void 0 : _22.preconditions, 20, 500),
3483
+ successEvidence: cleanStringList((_23 = nextActionContractGate.metadata) === null || _23 === void 0 ? void 0 : _23.successEvidence, 20, 500),
3484
+ requiredHotfixCommitProof: cleanStringList((_24 = nextActionContractGate.metadata) === null || _24 === void 0 ? void 0 : _24.requiredHotfixCommitProof, 20, 240),
3485
+ stopConditions: cleanStringList((_25 = nextActionContractGate.metadata) === null || _25 === void 0 ? void 0 : _25.stopConditions, 20, 500),
3486
+ forbiddenActions: cleanStringList((_26 = nextActionContractGate.metadata) === null || _26 === void 0 ? void 0 : _26.forbiddenActions, 20, 500),
3487
+ nextCommands: cleanStringList((_27 = nextActionContractGate.metadata) === null || _27 === void 0 ? void 0 : _27.nextCommands, 20, 240),
3488
+ blockers: cleanStringList((_28 = nextActionContractGate.metadata) === null || _28 === void 0 ? void 0 : _28.blockers, 20, 500)
3303
3489
  } : undefined
3304
3490
  }
3305
3491
  });
@@ -3412,6 +3598,16 @@ function buildAssistantAIRunFromEvidence(input) {
3412
3598
  recordedAt: answerQualityGate.recordedAt,
3413
3599
  metadata: answerQualityGate.metadata
3414
3600
  });
3601
+ var answerActionabilityContract = buildAssistantAnswerActionabilityContract(answerQualityDecision, input.now);
3602
+ var answerActionabilityGate = assistantAnswerActionabilityGate(answerActionabilityContract, input.now);
3603
+ pushEvent(events, {
3604
+ type: 'assistant_message',
3605
+ category: 'assistant_answer_actionability',
3606
+ message: answerActionabilityGate.reason,
3607
+ artifactPaths: answerActionabilityGate.evidenceRefs,
3608
+ recordedAt: answerActionabilityGate.recordedAt,
3609
+ metadata: answerActionabilityGate.metadata
3610
+ });
3415
3611
  var correctnessChecks = asArray(input.correctnessChecks);
3416
3612
  var hasPassedCorrectnessCheck = correctnessChecks.some(function (check) { return /^(pass|passed|success|ok)$/i.test(cleanText(check.status || (check.passed === true ? 'pass' : ''), 80)); });
3417
3613
  var correctnessEvidence = {
@@ -3455,6 +3651,7 @@ function buildAssistantAIRunFromEvidence(input) {
3455
3651
  startedAt: dateValue(conversation, ['startedAt', 'createdAt']),
3456
3652
  completedAt: dateValue(conversation, ['completedAt', 'closedAt', 'updatedAt']),
3457
3653
  events: events,
3654
+ gates: [answerActionabilityGate],
3458
3655
  qa: qa,
3459
3656
  cost: cost,
3460
3657
  rejected: failedReports.length > 0 || conversation.rejected === true,
@@ -3485,6 +3682,28 @@ function buildAssistantAIRunFromEvidence(input) {
3485
3682
  queryExecutionCount: answerQualityDecision.queryExecutionCount,
3486
3683
  nextActions: answerQualityDecision.nextActions,
3487
3684
  blockers: answerQualityDecision.blockers
3685
+ },
3686
+ answerActionability: {
3687
+ contractId: answerActionabilityContract.contractId,
3688
+ status: answerActionabilityContract.status,
3689
+ primaryCommand: answerActionabilityContract.primaryCommand,
3690
+ label: answerActionabilityContract.label,
3691
+ canAnswerCustomer: answerActionabilityContract.canAnswerCustomer,
3692
+ canDraftSupportReply: answerActionabilityContract.canDraftSupportReply,
3693
+ canSendCustomerReply: answerActionabilityContract.canSendCustomerReply,
3694
+ requiresHumanReview: answerActionabilityContract.requiresHumanReview,
3695
+ canRunWithoutCodexMonitor: answerActionabilityContract.canRunWithoutCodexMonitor,
3696
+ codexFallbackRequired: answerActionabilityContract.codexFallbackRequired,
3697
+ costRisk: answerActionabilityContract.costRisk,
3698
+ queryResultClass: answerActionabilityContract.queryResultClass,
3699
+ confidenceLevel: answerActionabilityContract.confidenceLevel,
3700
+ decisionBasis: answerActionabilityContract.decisionBasis,
3701
+ requiredEvidence: answerActionabilityContract.requiredEvidence,
3702
+ successEvidence: answerActionabilityContract.successEvidence,
3703
+ blockers: answerActionabilityContract.blockers,
3704
+ nextActions: answerActionabilityContract.nextActions,
3705
+ nextCommands: answerActionabilityContract.nextCommands,
3706
+ forbiddenActions: answerActionabilityContract.forbiddenActions
3488
3707
  }
3489
3708
  }
3490
3709
  });