@hongmaple0820/scale-engine 0.29.0 → 0.33.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/README.en.md +2 -0
- package/README.md +2 -0
- package/dist/api/cli.js +4 -0
- package/dist/api/cli.js.map +1 -1
- package/dist/evolution/SessionLearnings.d.ts +70 -0
- package/dist/evolution/SessionLearnings.js +217 -0
- package/dist/evolution/SessionLearnings.js.map +1 -0
- package/dist/runtime/AiOsRuntime.d.ts +99 -1
- package/dist/runtime/AiOsRuntime.js +462 -14
- package/dist/runtime/AiOsRuntime.js.map +1 -1
- package/dist/skills/RoleSkills.d.ts +20 -0
- package/dist/skills/RoleSkills.js +154 -0
- package/dist/skills/RoleSkills.js.map +1 -0
- package/dist/skills/SkillDiscovery.d.ts +5 -0
- package/dist/skills/SkillDiscovery.js +15 -0
- package/dist/skills/SkillDiscovery.js.map +1 -1
- package/dist/skills/SkillFrontmatter.d.ts +28 -0
- package/dist/skills/SkillFrontmatter.js +152 -0
- package/dist/skills/SkillFrontmatter.js.map +1 -0
- package/dist/skills/SkillRegistry.d.ts +11 -0
- package/dist/skills/SkillRegistry.js +12 -0
- package/dist/skills/SkillRegistry.js.map +1 -1
- package/dist/skills/index.d.ts +1 -0
- package/dist/skills/index.js +1 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/testing/DiffTestSelector.d.ts +22 -0
- package/dist/testing/DiffTestSelector.js +114 -0
- package/dist/testing/DiffTestSelector.js.map +1 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/workflow/AdaptiveWorkflowRouter.d.ts +37 -0
- package/dist/workflow/AdaptiveWorkflowRouter.js +211 -0
- package/dist/workflow/AdaptiveWorkflowRouter.js.map +1 -0
- package/dist/workflow/EvolutionShadowPromoter.d.ts +46 -0
- package/dist/workflow/EvolutionShadowPromoter.js +73 -0
- package/dist/workflow/EvolutionShadowPromoter.js.map +1 -0
- package/dist/workflow/ReviewAnalyzer.d.ts +15 -0
- package/dist/workflow/ReviewAnalyzer.js +82 -0
- package/dist/workflow/ReviewAnalyzer.js.map +1 -1
- package/dist/workflow/SecurityAudit.d.ts +27 -0
- package/dist/workflow/SecurityAudit.js +294 -0
- package/dist/workflow/SecurityAudit.js.map +1 -0
- package/dist/workflow/SessionPreamble.d.ts +19 -0
- package/dist/workflow/SessionPreamble.js +125 -0
- package/dist/workflow/SessionPreamble.js.map +1 -0
- package/dist/workflow/ShipPipeline.d.ts +30 -0
- package/dist/workflow/ShipPipeline.js +366 -0
- package/dist/workflow/ShipPipeline.js.map +1 -0
- package/dist/workflow/WorkflowGuidance.d.ts +5 -1
- package/dist/workflow/WorkflowGuidance.js +31 -0
- package/dist/workflow/WorkflowGuidance.js.map +1 -1
- package/dist/workflow/index.d.ts +5 -0
- package/dist/workflow/index.js +5 -0
- package/dist/workflow/index.js.map +1 -1
- package/docs/AI_ENGINEERING_OS_POSITIONING.md +9 -0
- package/docs/CONTEXT_BUDGET.md +1 -1
- package/package.json +1 -1
|
@@ -5,10 +5,14 @@ import { createGovernanceRoiReport, } from '../governance/GovernanceRoi.js';
|
|
|
5
5
|
import { evaluateProgressiveGovernance, } from '../governance/ProgressiveGovernance.js';
|
|
6
6
|
import { MemoryFabric, recallMemoryProviders, } from '../memory/index.js';
|
|
7
7
|
import { createSkillPlan, loadSkillRoutingPolicy, } from '../skills/routing/index.js';
|
|
8
|
+
import { routeAdaptiveWorkflow } from '../workflow/AdaptiveWorkflowRouter.js';
|
|
9
|
+
import { proposeShadowRule, buildEvolutionShadowReport, } from '../workflow/EvolutionShadowPromoter.js';
|
|
8
10
|
import { runSafeCommand } from '../tools/SafeCommandRunner.js';
|
|
9
11
|
import { SCALE_ENGINE_VERSION } from '../version.js';
|
|
10
12
|
import { resolveVerificationTargets, } from '../workflow/VerificationProfile.js';
|
|
11
13
|
import { RuntimeEvidenceLedger } from './RuntimeEvidenceLedger.js';
|
|
14
|
+
import { loadRelevantLearnings } from '../evolution/SessionLearnings.js';
|
|
15
|
+
import { collectSessionPreamble } from '../workflow/SessionPreamble.js';
|
|
12
16
|
export async function createAiOsPlan(input) {
|
|
13
17
|
const projectDir = resolve(input.projectDir ?? process.cwd());
|
|
14
18
|
const scaleDir = input.scaleDir ?? '.scale';
|
|
@@ -17,6 +21,8 @@ export async function createAiOsPlan(input) {
|
|
|
17
21
|
const services = input.services ?? [];
|
|
18
22
|
const taskId = input.taskId;
|
|
19
23
|
const budget = input.budget ?? 8_000;
|
|
24
|
+
const preamble = collectSessionPreamble({ projectDir, scaleDir });
|
|
25
|
+
const sessionLearnings = loadRelevantLearnings({ projectDir, scaleDir, task: input.task, limit: 5 });
|
|
20
26
|
const governance = evaluateProgressiveGovernance({
|
|
21
27
|
task: input.task,
|
|
22
28
|
changedFiles: files,
|
|
@@ -62,7 +68,15 @@ export async function createAiOsPlan(input) {
|
|
|
62
68
|
services,
|
|
63
69
|
policy: skillPolicy,
|
|
64
70
|
});
|
|
65
|
-
const
|
|
71
|
+
const evaluator = createEvaluatorIntelligence({
|
|
72
|
+
task: input.task,
|
|
73
|
+
files,
|
|
74
|
+
governance,
|
|
75
|
+
skillPlan,
|
|
76
|
+
});
|
|
77
|
+
const toolStrategy = createToolStrategyPlan(skillPlan);
|
|
78
|
+
const adaptiveWorkflow = createAdaptiveWorkflow(governance, skillPlan, evaluator, toolStrategy);
|
|
79
|
+
const evolutionShadow = createEvolutionShadowProposals(governance, evaluator);
|
|
66
80
|
const roi = createGovernanceRoiReport({
|
|
67
81
|
taskId,
|
|
68
82
|
contextBudget,
|
|
@@ -81,8 +95,12 @@ export async function createAiOsPlan(input) {
|
|
|
81
95
|
files,
|
|
82
96
|
services,
|
|
83
97
|
},
|
|
98
|
+
preamble,
|
|
84
99
|
governance,
|
|
85
100
|
adaptiveWorkflow,
|
|
101
|
+
evaluator,
|
|
102
|
+
toolStrategy,
|
|
103
|
+
evolutionShadow,
|
|
86
104
|
context,
|
|
87
105
|
memory: {
|
|
88
106
|
providerOrder: memoryRecall.providerOrder,
|
|
@@ -93,8 +111,9 @@ export async function createAiOsPlan(input) {
|
|
|
93
111
|
contextPack: memoryPack,
|
|
94
112
|
},
|
|
95
113
|
skillPlan,
|
|
114
|
+
sessionLearnings,
|
|
96
115
|
roi,
|
|
97
|
-
recommendations: recommendations({ governance, context, memoryRecall, skillPlan }),
|
|
116
|
+
recommendations: recommendations({ governance, context, memoryRecall, skillPlan, evaluator, toolStrategy }),
|
|
98
117
|
};
|
|
99
118
|
}
|
|
100
119
|
export async function createAiOsRun(input) {
|
|
@@ -194,6 +213,7 @@ export async function createAiOsBenchmark(input = {}) {
|
|
|
194
213
|
task: scenario.task,
|
|
195
214
|
level: scenario.level,
|
|
196
215
|
governanceMode: plan.governance.effectiveMode,
|
|
216
|
+
workflowProfile: plan.adaptiveWorkflow.profile,
|
|
197
217
|
metrics: {
|
|
198
218
|
estimatedTokens: plan.context.totalEstimatedTokens,
|
|
199
219
|
budget: plan.context.task.budget,
|
|
@@ -202,6 +222,10 @@ export async function createAiOsBenchmark(input = {}) {
|
|
|
202
222
|
selectedProviders: plan.memory.selectedProviders,
|
|
203
223
|
skillSteps: plan.skillPlan.executionPlan.steps.length,
|
|
204
224
|
requiredSkillSteps: plan.skillPlan.executionPlan.steps.filter(step => step.required).length,
|
|
225
|
+
evaluatorGates: plan.evaluator.gates.length,
|
|
226
|
+
toolStrategySteps: plan.toolStrategy.summary.totalSteps,
|
|
227
|
+
toolStrategyCostUnits: plan.toolStrategy.summary.estimatedCostUnits,
|
|
228
|
+
evolutionProposals: plan.evolutionShadow.summary.totalProposals,
|
|
205
229
|
gates: plan.adaptiveWorkflow.gates.length,
|
|
206
230
|
roiModules: plan.roi.modules.length,
|
|
207
231
|
},
|
|
@@ -556,6 +580,9 @@ function buildAiOsIntelligenceReport(input) {
|
|
|
556
580
|
const totalMemoryItems = runMemoryItems.length + benchmarkMemoryItems;
|
|
557
581
|
const memoryQuality = summarizeMemoryQuality(runMemoryItems);
|
|
558
582
|
const contextQuality = summarizeContextQuality(input.runReports);
|
|
583
|
+
const evaluatorQuality = summarizeEvaluatorQuality(input.runReports, input.benchmark);
|
|
584
|
+
const toolStrategyQuality = summarizeToolStrategyQuality(input.runReports, input.benchmark);
|
|
585
|
+
const evolutionQuality = summarizeEvolutionQuality(input.runReports, input.benchmark);
|
|
559
586
|
const contextSignalStatus = contextQuality.compressionRisk === 'high'
|
|
560
587
|
? 'warning'
|
|
561
588
|
: estimatedTokenSavings > 0 ? 'ready' : input.runReports.length > 0 || input.benchmark ? 'warning' : 'blocked';
|
|
@@ -571,10 +598,24 @@ function buildAiOsIntelligenceReport(input) {
|
|
|
571
598
|
...input.runReports.flatMap(report => report.plan.skillPlan.executionPlan.steps.map(step => `${report.artifacts.runReport}:${step.id}`)),
|
|
572
599
|
...(input.benchmark ? [`${input.benchmarkReport}:steps=${input.benchmark.summary.totalSkillSteps}`] : []),
|
|
573
600
|
];
|
|
601
|
+
const evaluatorEvidence = [
|
|
602
|
+
...input.runReports.flatMap(report => resolveRunEvaluator(report).gates.map(gate => `${report.artifacts.runReport}:${gate.id}`)),
|
|
603
|
+
...(input.benchmark ? [`${input.benchmarkReport}:evaluator-gates=${input.benchmark.summary.totalEvaluatorGates}`] : []),
|
|
604
|
+
];
|
|
605
|
+
const toolStrategyEvidence = [
|
|
606
|
+
...input.runReports.flatMap(report => resolveRunToolStrategy(report).nodes.map(node => `${report.artifacts.runReport}:${node.id}`)),
|
|
607
|
+
...(input.benchmark ? [`${input.benchmarkReport}:tool-strategy=${input.benchmark.summary.totalToolStrategySteps}`] : []),
|
|
608
|
+
];
|
|
609
|
+
const evolutionEvidence = [
|
|
610
|
+
...input.runReports.flatMap(report => (report.plan.evolutionShadow?.proposals ?? []).map(p => `${report.artifacts.runReport}:${p.id}:${p.maturity.stage}`)),
|
|
611
|
+
...(input.benchmark ? [`${input.benchmarkReport}:evolution-proposals=${input.benchmark.summary.totalEvolutionProposals}`] : []),
|
|
612
|
+
];
|
|
574
613
|
const benchmarkEvidence = input.benchmark ? [
|
|
575
614
|
`${input.benchmarkReport}:scenarios=${input.benchmark.summary.scenarios}`,
|
|
576
615
|
`${input.benchmarkReport}:memory=${input.benchmark.summary.totalMemoryItems}`,
|
|
577
616
|
`${input.benchmarkReport}:skills=${input.benchmark.summary.totalSkillSteps}`,
|
|
617
|
+
`${input.benchmarkReport}:evaluator-gates=${input.benchmark.summary.totalEvaluatorGates}`,
|
|
618
|
+
`${input.benchmarkReport}:tool-strategy=${input.benchmark.summary.totalToolStrategySteps}`,
|
|
578
619
|
] : [input.benchmarkReport];
|
|
579
620
|
const signals = [
|
|
580
621
|
{
|
|
@@ -614,6 +655,57 @@ function buildAiOsIntelligenceReport(input) {
|
|
|
614
655
|
? ['Use skill routing evidence in reviews to check why a skill, MCP, or CLI path was selected.']
|
|
615
656
|
: ['Create a task with files or services that should trigger required skill routing.'],
|
|
616
657
|
},
|
|
658
|
+
{
|
|
659
|
+
id: 'evaluator-intelligence',
|
|
660
|
+
status: evaluatorQuality.requiredGates > 0
|
|
661
|
+
? evaluatorQuality.averageUncertainty >= 0.7 ? 'warning' : 'ready'
|
|
662
|
+
: input.runReports.length > 0 || input.benchmark ? 'warning' : 'blocked',
|
|
663
|
+
summary: evaluatorQuality.requiredGates > 0
|
|
664
|
+
? `${evaluatorQuality.requiredGates} evaluator gate(s) required; average uncertainty ${evaluatorQuality.averageUncertainty}.`
|
|
665
|
+
: 'No evaluator gate evidence found for architecture, root-cause, security, or release reasoning.',
|
|
666
|
+
evidence: evaluatorEvidence,
|
|
667
|
+
recommendations: evaluatorQuality.requiredGates > 0
|
|
668
|
+
? ['Use evaluator gates to force critique, uncertainty logging, and review evidence before promoting reasoning-heavy work.']
|
|
669
|
+
: ['Run a reasoning-heavy AI OS task so evaluator intelligence can prove critique coverage.'],
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
id: 'tool-strategy',
|
|
673
|
+
status: toolStrategyQuality.totalSteps > 0
|
|
674
|
+
? toolStrategyQuality.fallbackCoverage < 1 ? 'warning' : 'ready'
|
|
675
|
+
: input.runReports.length > 0 || input.benchmark ? 'warning' : 'blocked',
|
|
676
|
+
summary: toolStrategyQuality.totalSteps > 0
|
|
677
|
+
? `${toolStrategyQuality.totalSteps} tool strategy step(s); ${toolStrategyQuality.highRiskSteps} high-risk; fallback coverage ${toolStrategyQuality.fallbackCoverage}.`
|
|
678
|
+
: 'No tool strategy graph found for skills, artifacts, CLI, MCP, or verification steps.',
|
|
679
|
+
evidence: toolStrategyEvidence,
|
|
680
|
+
recommendations: toolStrategyQuality.totalSteps > 0
|
|
681
|
+
? ['Use tool strategy evidence to review cost, retry, fallback, and side-effect risk before execution.']
|
|
682
|
+
: ['Create a task that triggers skill routing so the AI OS can build a tool strategy graph.'],
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
id: 'adaptive-workflow',
|
|
686
|
+
status: input.runReports.some(r => r.plan.adaptiveWorkflow.profile) ? 'ready' : input.runReports.length > 0 || input.benchmark ? 'warning' : 'blocked',
|
|
687
|
+
summary: summarizeAdaptiveWorkflowSignal(input.runReports, input.benchmark),
|
|
688
|
+
evidence: [
|
|
689
|
+
...input.runReports.map(r => `${r.artifacts.runReport}:profile=${r.plan.adaptiveWorkflow.profile}`),
|
|
690
|
+
...(input.benchmark ? [`${input.benchmarkReport}:profiles=${input.benchmark.summary.workflowProfiles.join(',')}`] : []),
|
|
691
|
+
],
|
|
692
|
+
recommendations: input.runReports.some(r => r.plan.adaptiveWorkflow.profile)
|
|
693
|
+
? ['Use workflow profile distribution to verify that risk signals correctly escalate governance.']
|
|
694
|
+
: ['Run an AI OS task with mixed risk levels to prove adaptive workflow routing.'],
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
id: 'evolution-shadow',
|
|
698
|
+
status: evolutionQuality.proposals > 0
|
|
699
|
+
? evolutionQuality.pendingValidation > 0 ? 'warning' : 'ready'
|
|
700
|
+
: input.runReports.length > 0 || input.benchmark ? 'warning' : 'blocked',
|
|
701
|
+
summary: evolutionQuality.proposals > 0
|
|
702
|
+
? `${evolutionQuality.proposals} shadow proposal(s); ${evolutionQuality.shadowRules} shadow, ${evolutionQuality.candidateHooks} candidate-hook, ${evolutionQuality.approvedBlocking} approved-blocking.`
|
|
703
|
+
: 'No evolution shadow proposals found. Run tasks with high-risk governance signals or evaluator gates to generate shadow rule candidates.',
|
|
704
|
+
evidence: evolutionEvidence,
|
|
705
|
+
recommendations: evolutionQuality.proposals > 0
|
|
706
|
+
? ['Review shadow rule proposals and validate before promotion to candidate-hook or approved-blocking.']
|
|
707
|
+
: ['Run a high-risk AI OS task so evolution shadow promotion can propose rules from governance and evaluator signals.'],
|
|
708
|
+
},
|
|
617
709
|
{
|
|
618
710
|
id: 'benchmark-intelligence',
|
|
619
711
|
status: input.benchmark && input.benchmarkStatus === 'fresh'
|
|
@@ -636,6 +728,9 @@ function buildAiOsIntelligenceReport(input) {
|
|
|
636
728
|
selectedProviders,
|
|
637
729
|
memoryQuality,
|
|
638
730
|
contextQuality,
|
|
731
|
+
evaluatorQuality,
|
|
732
|
+
toolStrategyQuality,
|
|
733
|
+
evolutionQuality,
|
|
639
734
|
estimatedTokenSavings,
|
|
640
735
|
skillSteps,
|
|
641
736
|
};
|
|
@@ -668,6 +763,91 @@ function summarizeContextQuality(runReports) {
|
|
|
668
763
|
compressionRisk,
|
|
669
764
|
};
|
|
670
765
|
}
|
|
766
|
+
function summarizeEvaluatorQuality(runReports, benchmark) {
|
|
767
|
+
const runEvaluators = runReports.map(resolveRunEvaluator);
|
|
768
|
+
const runGates = runEvaluators.flatMap(evaluator => evaluator.gates);
|
|
769
|
+
const benchmarkGateCount = benchmark?.summary.totalEvaluatorGates ?? 0;
|
|
770
|
+
const uncertaintyScores = runEvaluators.map(evaluator => evaluator.uncertainty.score);
|
|
771
|
+
const gateIds = new Set(runGates.map(gate => gate.id));
|
|
772
|
+
if (benchmarkGateCount > 0)
|
|
773
|
+
gateIds.add('uncertainty-decision-log');
|
|
774
|
+
return {
|
|
775
|
+
requiredGates: runGates.filter(gate => gate.required).length + benchmarkGateCount,
|
|
776
|
+
highRiskPlans: runEvaluators.filter(evaluator => evaluator.riskLevel === 'high').length,
|
|
777
|
+
averageUncertainty: roundMetric(average(uncertaintyScores)),
|
|
778
|
+
gateIds: [...gateIds].sort(),
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
function resolveRunEvaluator(report) {
|
|
782
|
+
const plan = report.plan;
|
|
783
|
+
return plan.evaluator ?? createEvaluatorIntelligence({
|
|
784
|
+
task: report.plan.task.task,
|
|
785
|
+
files: report.plan.task.files,
|
|
786
|
+
governance: report.plan.governance,
|
|
787
|
+
skillPlan: report.plan.skillPlan,
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
function summarizeToolStrategyQuality(runReports, benchmark) {
|
|
791
|
+
const runStrategies = runReports.map(resolveRunToolStrategy);
|
|
792
|
+
const runSummary = runStrategies.reduce((summary, strategy) => ({
|
|
793
|
+
totalSteps: summary.totalSteps + strategy.summary.totalSteps,
|
|
794
|
+
requiredSteps: summary.requiredSteps + strategy.summary.requiredSteps,
|
|
795
|
+
highRiskSteps: summary.highRiskSteps + strategy.summary.highRiskSteps,
|
|
796
|
+
estimatedCostUnits: summary.estimatedCostUnits + strategy.summary.estimatedCostUnits,
|
|
797
|
+
fallbackCoveredSteps: summary.fallbackCoveredSteps + strategy.summary.fallbackCoveredSteps,
|
|
798
|
+
}), {
|
|
799
|
+
totalSteps: 0,
|
|
800
|
+
requiredSteps: 0,
|
|
801
|
+
highRiskSteps: 0,
|
|
802
|
+
estimatedCostUnits: 0,
|
|
803
|
+
fallbackCoveredSteps: 0,
|
|
804
|
+
});
|
|
805
|
+
const benchmarkSteps = benchmark?.summary.totalToolStrategySteps ?? 0;
|
|
806
|
+
const benchmarkCost = benchmark?.summary.totalToolStrategyCostUnits ?? 0;
|
|
807
|
+
const totalSteps = runSummary.totalSteps + benchmarkSteps;
|
|
808
|
+
const fallbackCoveredSteps = runSummary.fallbackCoveredSteps + benchmarkSteps;
|
|
809
|
+
return {
|
|
810
|
+
totalSteps,
|
|
811
|
+
requiredSteps: runSummary.requiredSteps,
|
|
812
|
+
highRiskSteps: runSummary.highRiskSteps,
|
|
813
|
+
estimatedCostUnits: runSummary.estimatedCostUnits + benchmarkCost,
|
|
814
|
+
fallbackCoverage: totalSteps > 0 ? roundMetric(fallbackCoveredSteps / totalSteps) : 0,
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
function resolveRunToolStrategy(report) {
|
|
818
|
+
const plan = report.plan;
|
|
819
|
+
return plan.toolStrategy ?? createToolStrategyPlan(report.plan.skillPlan);
|
|
820
|
+
}
|
|
821
|
+
function summarizeEvolutionQuality(runReports, benchmark) {
|
|
822
|
+
const runProposals = runReports.flatMap(r => r.plan.evolutionShadow?.proposals ?? []);
|
|
823
|
+
const benchmarkProposals = benchmark?.summary.totalEvolutionProposals ?? 0;
|
|
824
|
+
const allProposals = runProposals;
|
|
825
|
+
const stageCount = (stage) => allProposals.filter(p => p.maturity.stage === stage).length;
|
|
826
|
+
return {
|
|
827
|
+
proposals: allProposals.length + benchmarkProposals,
|
|
828
|
+
shadowRules: stageCount('shadow'),
|
|
829
|
+
candidateHooks: stageCount('candidate-hook'),
|
|
830
|
+
approvedBlocking: stageCount('approved-blocking'),
|
|
831
|
+
pendingValidation: allProposals.filter(p => p.maturity.stage === 'shadow' && p.maturity.shadowHits < 10).length,
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
function resolveRunEvolutionShadow(report) {
|
|
835
|
+
const plan = report.plan;
|
|
836
|
+
return plan.evolutionShadow ?? buildEvolutionShadowReport([]);
|
|
837
|
+
}
|
|
838
|
+
function summarizeAdaptiveWorkflowSignal(runReports, benchmark) {
|
|
839
|
+
const profiles = runReports.map(r => r.plan.adaptiveWorkflow.profile);
|
|
840
|
+
const benchmarkProfiles = benchmark?.summary.workflowProfiles ?? [];
|
|
841
|
+
const allProfiles = [...profiles, ...benchmarkProfiles];
|
|
842
|
+
if (allProfiles.length === 0)
|
|
843
|
+
return 'No adaptive workflow profile evidence found.';
|
|
844
|
+
const distribution = new Map();
|
|
845
|
+
for (const p of allProfiles)
|
|
846
|
+
distribution.set(p, (distribution.get(p) ?? 0) + 1);
|
|
847
|
+
const parts = [...distribution.entries()].map(([p, n]) => `${p}=${n}`).join(', ');
|
|
848
|
+
const escalated = runReports.filter(r => r.plan.adaptiveWorkflow.escalationReasons.length > 0).length;
|
|
849
|
+
return `${allProfiles.length} run(s) with profile distribution: ${parts}. ${escalated} run(s) had escalation reasons.`;
|
|
850
|
+
}
|
|
671
851
|
function summarizeMemoryQuality(items) {
|
|
672
852
|
if (items.length === 0) {
|
|
673
853
|
return {
|
|
@@ -756,16 +936,20 @@ function buildRunSteps(plan) {
|
|
|
756
936
|
evidence: ['memory.providerOrder', 'memory.selectedProviders', 'memory.items'],
|
|
757
937
|
dependsOn: ['runtime-plan'],
|
|
758
938
|
});
|
|
939
|
+
const profile = plan.adaptiveWorkflow.profile;
|
|
759
940
|
for (const gate of plan.adaptiveWorkflow.gates) {
|
|
760
941
|
if (steps.has(gate))
|
|
761
942
|
continue;
|
|
943
|
+
const gateRequired = profile !== 'light';
|
|
762
944
|
upsert({
|
|
763
945
|
id: gate,
|
|
764
946
|
kind: gate === 'runtime-evidence' ? 'evidence' : 'gate',
|
|
765
947
|
title: `Satisfy ${gate} gate`,
|
|
766
948
|
status: 'planned',
|
|
767
|
-
required:
|
|
768
|
-
summary:
|
|
949
|
+
required: gateRequired,
|
|
950
|
+
summary: gateRequired
|
|
951
|
+
? `Required by ${plan.adaptiveWorkflow.strategy} in ${profile} profile (${plan.adaptiveWorkflow.mode} mode).`
|
|
952
|
+
: `Advisory in ${profile} profile; not blocking completion.`,
|
|
769
953
|
evidence: [`gate.${gate}`],
|
|
770
954
|
dependsOn: ['runtime-plan'],
|
|
771
955
|
});
|
|
@@ -1317,7 +1501,12 @@ function summarizeBenchmark(results) {
|
|
|
1317
1501
|
totalMemoryItems: results.reduce((sum, result) => sum + result.metrics.memoryItems, 0),
|
|
1318
1502
|
totalSkillSteps: results.reduce((sum, result) => sum + result.metrics.skillSteps, 0),
|
|
1319
1503
|
requiredSkillSteps: results.reduce((sum, result) => sum + result.metrics.requiredSkillSteps, 0),
|
|
1504
|
+
totalEvaluatorGates: results.reduce((sum, result) => sum + result.metrics.evaluatorGates, 0),
|
|
1505
|
+
totalToolStrategySteps: results.reduce((sum, result) => sum + result.metrics.toolStrategySteps, 0),
|
|
1506
|
+
totalToolStrategyCostUnits: results.reduce((sum, result) => sum + result.metrics.toolStrategyCostUnits, 0),
|
|
1507
|
+
totalEvolutionProposals: results.reduce((sum, result) => sum + result.metrics.evolutionProposals, 0),
|
|
1320
1508
|
governanceModes: [...new Set(results.map(result => result.governanceMode))],
|
|
1509
|
+
workflowProfiles: [...new Set(results.map(result => result.workflowProfile))],
|
|
1321
1510
|
averageTokenUtilization: totalBudget > 0 ? Number((totalEstimatedTokens / totalBudget).toFixed(4)) : 0,
|
|
1322
1511
|
};
|
|
1323
1512
|
}
|
|
@@ -1325,6 +1514,10 @@ function benchmarkRecommendations(summary) {
|
|
|
1325
1514
|
const recommendations = ['Use benchmark deltas in release notes only after comparing the same scenario set across versions.'];
|
|
1326
1515
|
if (summary.totalSkillSteps === 0)
|
|
1327
1516
|
recommendations.push('Skill routing did not produce steps; inspect skill policy detection.');
|
|
1517
|
+
if (summary.totalEvaluatorGates === 0)
|
|
1518
|
+
recommendations.push('Evaluator intelligence did not require any critique gate; add reasoning-heavy benchmark scenarios before claiming evaluator coverage.');
|
|
1519
|
+
if (summary.totalToolStrategySteps === 0)
|
|
1520
|
+
recommendations.push('Tool strategy did not build a cost/retry/fallback graph; inspect skill execution plan coverage.');
|
|
1328
1521
|
if (summary.averageTokenUtilization > 0.9)
|
|
1329
1522
|
recommendations.push('Context utilization is high; lower budgets or improve relevance filtering before scaling.');
|
|
1330
1523
|
if (!summary.governanceModes.includes('critical') && !summary.governanceModes.includes('expanded')) {
|
|
@@ -1332,29 +1525,278 @@ function benchmarkRecommendations(summary) {
|
|
|
1332
1525
|
}
|
|
1333
1526
|
return recommendations;
|
|
1334
1527
|
}
|
|
1335
|
-
function createAdaptiveWorkflow(governance, skillPlan) {
|
|
1528
|
+
function createAdaptiveWorkflow(governance, skillPlan, evaluator, toolStrategy) {
|
|
1529
|
+
const routerResult = routeAdaptiveWorkflow({ governance, evaluator, toolStrategy });
|
|
1336
1530
|
const gates = new Set();
|
|
1337
1531
|
gates.add('context-compiler');
|
|
1338
1532
|
gates.add('memory-provider-recall');
|
|
1339
1533
|
if (skillPlan.required || skillPlan.executionPlan.steps.length > 0)
|
|
1340
1534
|
gates.add('skill-evidence');
|
|
1341
1535
|
gates.add('runtime-evidence');
|
|
1342
|
-
if (
|
|
1536
|
+
if (routerResult.profile === 'strict' || routerResult.profile === 'critical')
|
|
1343
1537
|
gates.add('impact-analysis');
|
|
1344
|
-
if (
|
|
1538
|
+
if (routerResult.profile === 'critical')
|
|
1345
1539
|
gates.add('security-review');
|
|
1540
|
+
for (const gate of evaluator.gates)
|
|
1541
|
+
gates.add(gate.id);
|
|
1542
|
+
for (const override of routerResult.gateOverrides)
|
|
1543
|
+
gates.add(override.gateId);
|
|
1544
|
+
const requiredBehaviors = new Set(governance.requiredBehaviors);
|
|
1545
|
+
for (const constraint of routerResult.behavioralConstraints) {
|
|
1546
|
+
if (constraint.required)
|
|
1547
|
+
requiredBehaviors.add(constraint.description);
|
|
1548
|
+
}
|
|
1346
1549
|
return {
|
|
1347
1550
|
strategy: 'risk-adaptive-runtime-v1',
|
|
1551
|
+
profile: routerResult.profile,
|
|
1552
|
+
escalationReasons: routerResult.escalationReasons,
|
|
1348
1553
|
mode: governance.effectiveMode,
|
|
1349
|
-
requiredBehaviors:
|
|
1554
|
+
requiredBehaviors: Array.from(requiredBehaviors),
|
|
1350
1555
|
gates: Array.from(gates),
|
|
1351
|
-
exitCriteria:
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1556
|
+
exitCriteria: routerResult.exitCriteria,
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
function createEvaluatorIntelligence(input) {
|
|
1560
|
+
const haystack = `${input.task} ${input.files.join(' ')} ${input.governance.signals.map(signal => signal.id).join(' ')}`.toLowerCase();
|
|
1561
|
+
const gates = [];
|
|
1562
|
+
const addGate = (gate) => {
|
|
1563
|
+
if (gates.some(existing => existing.id === gate.id))
|
|
1564
|
+
return;
|
|
1565
|
+
gates.push(gate);
|
|
1566
|
+
};
|
|
1567
|
+
if (/architecture|architectural|design|strategy|boundary|refactor|runtime|platform|framework|架构|方案|设计|边界|平台/.test(haystack)) {
|
|
1568
|
+
addGate({
|
|
1569
|
+
id: 'architecture-critique',
|
|
1570
|
+
required: input.governance.effectiveMode !== 'minimal',
|
|
1571
|
+
reason: 'Architecture, runtime, platform, or design decisions need an explicit critique before implementation claims.',
|
|
1572
|
+
evidence: matchingEvidence(input.files, /architecture|runtime|framework|docs|readme|src/i),
|
|
1573
|
+
});
|
|
1574
|
+
}
|
|
1575
|
+
if (/root cause|diagnose|debug|failure|incident|postmortem|regression|blocked|根因|排查|故障|事故|回归/.test(haystack)) {
|
|
1576
|
+
addGate({
|
|
1577
|
+
id: 'root-cause-review',
|
|
1578
|
+
required: true,
|
|
1579
|
+
reason: 'Failure diagnosis or root-cause work needs an alternate hypothesis check before closing.',
|
|
1580
|
+
evidence: matchingEvidence(input.files, /test|runtime|debug|log|src|docs/i),
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
if (input.governance.signals.some(signal => signal.id === 'critical-risk-domain' || signal.id === 'critical-file-path')) {
|
|
1584
|
+
addGate({
|
|
1585
|
+
id: 'security-threat-model',
|
|
1586
|
+
required: true,
|
|
1587
|
+
reason: 'Critical auth, data, production, or destructive risk requires threat-model review evidence.',
|
|
1588
|
+
evidence: input.governance.signals.flatMap(signal => signal.evidence).slice(0, 12),
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
if (/release|publish|deploy|migration|rollback|version|changelog|npm|ci|发版|发布|部署|迁移|回滚/.test(haystack)) {
|
|
1592
|
+
addGate({
|
|
1593
|
+
id: 'release-readiness-review',
|
|
1594
|
+
required: true,
|
|
1595
|
+
reason: 'Release, deployment, migration, or rollback work needs readiness and rollback evidence.',
|
|
1596
|
+
evidence: matchingEvidence(input.files, /package|changelog|release|deploy|migration|workflow|github/i),
|
|
1597
|
+
});
|
|
1598
|
+
}
|
|
1599
|
+
const drivers = evaluatorUncertaintyDrivers(input, gates);
|
|
1600
|
+
const uncertaintyScore = evaluatorUncertaintyScore(input, gates, drivers);
|
|
1601
|
+
if (gates.length > 0 || uncertaintyScore >= 0.45) {
|
|
1602
|
+
addGate({
|
|
1603
|
+
id: 'uncertainty-decision-log',
|
|
1604
|
+
required: uncertaintyScore >= 0.45 || input.governance.effectiveMode === 'critical',
|
|
1605
|
+
reason: 'The agent must record uncertainty, rejected alternatives, and evidence gaps before completion.',
|
|
1606
|
+
evidence: drivers,
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
const riskLevel = uncertaintyScore >= 0.7
|
|
1610
|
+
? 'high'
|
|
1611
|
+
: uncertaintyScore >= 0.4 || gates.some(gate => gate.required) ? 'medium' : 'low';
|
|
1612
|
+
return {
|
|
1613
|
+
strategy: 'evaluator-intelligence-v1',
|
|
1614
|
+
required: gates.some(gate => gate.required),
|
|
1615
|
+
riskLevel,
|
|
1616
|
+
uncertainty: {
|
|
1617
|
+
score: uncertaintyScore,
|
|
1618
|
+
threshold: 0.45,
|
|
1619
|
+
drivers,
|
|
1620
|
+
},
|
|
1621
|
+
gates,
|
|
1622
|
+
recommendations: evaluatorRecommendations(gates, riskLevel),
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
function createToolStrategyPlan(skillPlan) {
|
|
1626
|
+
const nodes = skillPlan.executionPlan.steps.map(step => {
|
|
1627
|
+
const risks = toolStepRisks(step.id, step.kind);
|
|
1628
|
+
return {
|
|
1629
|
+
id: `${step.kind}:${step.id}`,
|
|
1630
|
+
kind: step.kind,
|
|
1631
|
+
required: step.required,
|
|
1632
|
+
cost: {
|
|
1633
|
+
units: toolStepCostUnits(step.id, step.kind, step.required, risks),
|
|
1634
|
+
timeRisk: risks.timeRisk,
|
|
1635
|
+
sideEffectRisk: risks.sideEffectRisk,
|
|
1636
|
+
},
|
|
1637
|
+
retry: toolStepRetry(step.id, step.kind, risks),
|
|
1638
|
+
fallback: step.fallback,
|
|
1639
|
+
evidence: [step.evidenceRequired],
|
|
1640
|
+
};
|
|
1641
|
+
});
|
|
1642
|
+
const edges = buildToolStrategyEdges(nodes);
|
|
1643
|
+
const summary = {
|
|
1644
|
+
totalSteps: nodes.length,
|
|
1645
|
+
requiredSteps: nodes.filter(node => node.required).length,
|
|
1646
|
+
highRiskSteps: nodes.filter(node => node.cost.timeRisk === 'high' || node.cost.sideEffectRisk === 'high').length,
|
|
1647
|
+
estimatedCostUnits: nodes.reduce((sum, node) => sum + node.cost.units, 0),
|
|
1648
|
+
fallbackCoveredSteps: nodes.filter(node => node.fallback.trim().length > 0).length,
|
|
1357
1649
|
};
|
|
1650
|
+
return {
|
|
1651
|
+
strategy: 'tool-strategy-v1',
|
|
1652
|
+
nodes,
|
|
1653
|
+
edges,
|
|
1654
|
+
summary,
|
|
1655
|
+
recommendations: toolStrategyRecommendations(summary),
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
function createEvolutionShadowProposals(governance, evaluator) {
|
|
1659
|
+
const proposals = [];
|
|
1660
|
+
// Propose shadow rules from governance risk signals (escalated modes)
|
|
1661
|
+
for (const signal of governance.signals) {
|
|
1662
|
+
if (signal.mode === 'expanded' || signal.mode === 'critical') {
|
|
1663
|
+
proposals.push(proposeShadowRule({
|
|
1664
|
+
title: `Governance signal: ${signal.id}`,
|
|
1665
|
+
description: `Shadow rule from governance signal "${signal.id}" (mode=${signal.mode}). ${signal.reason}`,
|
|
1666
|
+
source: 'failure-learning',
|
|
1667
|
+
sourceEvidenceIds: signal.evidence.length > 0 ? signal.evidence : [signal.id],
|
|
1668
|
+
pattern: signal.id,
|
|
1669
|
+
enforcement: signal.mode === 'critical' ? 'hook' : 'prompt',
|
|
1670
|
+
rollback: `Remove shadow rule for governance signal "${signal.id}" if false positive rate exceeds threshold.`,
|
|
1671
|
+
}));
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
// Propose shadow rules from high-risk evaluator gates
|
|
1675
|
+
for (const gate of evaluator.gates) {
|
|
1676
|
+
if (gate.required && (gate.id === 'security-threat-model' || gate.id === 'root-cause-review')) {
|
|
1677
|
+
proposals.push(proposeShadowRule({
|
|
1678
|
+
title: `Evaluator gate: ${gate.id}`,
|
|
1679
|
+
description: `Shadow rule from required evaluator gate "${gate.id}". ${gate.reason}`,
|
|
1680
|
+
source: 'lesson-extraction',
|
|
1681
|
+
sourceEvidenceIds: [gate.id],
|
|
1682
|
+
pattern: gate.id,
|
|
1683
|
+
enforcement: 'prompt',
|
|
1684
|
+
rollback: `Remove shadow rule for evaluator gate "${gate.id}" if it does not reduce defect recurrence.`,
|
|
1685
|
+
}));
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
return buildEvolutionShadowReport(proposals);
|
|
1689
|
+
}
|
|
1690
|
+
function toolStepRisks(id, kind) {
|
|
1691
|
+
const normalized = id.toLowerCase();
|
|
1692
|
+
if (/desktop|cua|deploy|publish|release|migration|rollback|delete|drop|external|cli/.test(normalized)) {
|
|
1693
|
+
return { timeRisk: 'high', sideEffectRisk: 'high' };
|
|
1694
|
+
}
|
|
1695
|
+
if (/browser|e2e|playwright|screenshot|visual|security|threat|audit/.test(normalized)) {
|
|
1696
|
+
return { timeRisk: 'medium', sideEffectRisk: kind === 'verification' ? 'medium' : 'low' };
|
|
1697
|
+
}
|
|
1698
|
+
if (kind === 'artifact')
|
|
1699
|
+
return { timeRisk: 'low', sideEffectRisk: 'low' };
|
|
1700
|
+
if (kind === 'verification')
|
|
1701
|
+
return { timeRisk: 'medium', sideEffectRisk: 'medium' };
|
|
1702
|
+
return { timeRisk: 'medium', sideEffectRisk: 'low' };
|
|
1703
|
+
}
|
|
1704
|
+
function toolStepCostUnits(id, kind, required, risks) {
|
|
1705
|
+
let units = kind === 'artifact' ? 1 : kind === 'verification' ? 2 : 3;
|
|
1706
|
+
if (required)
|
|
1707
|
+
units += 1;
|
|
1708
|
+
if (risks.timeRisk === 'medium')
|
|
1709
|
+
units += 1;
|
|
1710
|
+
if (risks.timeRisk === 'high')
|
|
1711
|
+
units += 2;
|
|
1712
|
+
if (risks.sideEffectRisk === 'high')
|
|
1713
|
+
units += 2;
|
|
1714
|
+
if (/browser|e2e|desktop|external|cli|security|audit/i.test(id))
|
|
1715
|
+
units += 1;
|
|
1716
|
+
return units;
|
|
1717
|
+
}
|
|
1718
|
+
function toolStepRetry(id, kind, risks) {
|
|
1719
|
+
if (risks.sideEffectRisk === 'high')
|
|
1720
|
+
return { maxAttempts: 1, backoff: 'manual-review' };
|
|
1721
|
+
if (kind === 'verification')
|
|
1722
|
+
return { maxAttempts: /browser|e2e|playwright|network/i.test(id) ? 2 : 1, backoff: 'linear' };
|
|
1723
|
+
if (kind === 'skill')
|
|
1724
|
+
return { maxAttempts: 1, backoff: 'manual-review' };
|
|
1725
|
+
return { maxAttempts: 1, backoff: 'none' };
|
|
1726
|
+
}
|
|
1727
|
+
function buildToolStrategyEdges(nodes) {
|
|
1728
|
+
const edges = [];
|
|
1729
|
+
const skillNodes = nodes.filter(node => node.kind === 'skill');
|
|
1730
|
+
const artifactNodes = nodes.filter(node => node.kind === 'artifact');
|
|
1731
|
+
const verificationNodes = nodes.filter(node => node.kind === 'verification');
|
|
1732
|
+
for (const artifact of artifactNodes) {
|
|
1733
|
+
for (const skill of skillNodes.filter(node => node.required || artifact.required)) {
|
|
1734
|
+
edges.push({ from: skill.id, to: artifact.id, reason: 'Skill execution must leave artifact evidence when both are required or review-relevant.' });
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
for (const verification of verificationNodes) {
|
|
1738
|
+
for (const artifact of artifactNodes.filter(node => node.required)) {
|
|
1739
|
+
edges.push({ from: artifact.id, to: verification.id, reason: 'Required artifacts should exist before verification evidence is accepted.' });
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
return edges;
|
|
1743
|
+
}
|
|
1744
|
+
function toolStrategyRecommendations(summary) {
|
|
1745
|
+
if (summary.totalSteps === 0)
|
|
1746
|
+
return ['No tool strategy required; standard verification is enough for this task.'];
|
|
1747
|
+
const recommendations = ['Execute required tool strategy nodes before claiming task completion.'];
|
|
1748
|
+
if (summary.highRiskSteps > 0)
|
|
1749
|
+
recommendations.push('High-risk tool steps require manual review or explicit safe-mode evidence before retry.');
|
|
1750
|
+
if (summary.fallbackCoveredSteps < summary.totalSteps)
|
|
1751
|
+
recommendations.push('Fill fallback policy gaps before autonomous execution.');
|
|
1752
|
+
return recommendations;
|
|
1753
|
+
}
|
|
1754
|
+
function matchingEvidence(files, pattern) {
|
|
1755
|
+
return files.filter(file => pattern.test(file)).slice(0, 12);
|
|
1756
|
+
}
|
|
1757
|
+
function evaluatorUncertaintyDrivers(input, gates) {
|
|
1758
|
+
const drivers = new Set();
|
|
1759
|
+
if (input.governance.effectiveMode === 'critical')
|
|
1760
|
+
drivers.add('critical-governance-mode');
|
|
1761
|
+
if (input.governance.effectiveMode === 'expanded')
|
|
1762
|
+
drivers.add('expanded-governance-mode');
|
|
1763
|
+
if (input.files.length >= 6)
|
|
1764
|
+
drivers.add('wide-file-scope');
|
|
1765
|
+
if (input.skillPlan.executionPlan.steps.some(step => step.required))
|
|
1766
|
+
drivers.add('required-skill-evidence');
|
|
1767
|
+
for (const gate of gates)
|
|
1768
|
+
drivers.add(gate.id);
|
|
1769
|
+
if (/unknown|uncertain|maybe|assume|guess|可能|不确定|假设/.test(input.task.toLowerCase()))
|
|
1770
|
+
drivers.add('explicit-uncertainty-language');
|
|
1771
|
+
return [...drivers];
|
|
1772
|
+
}
|
|
1773
|
+
function evaluatorUncertaintyScore(input, gates, drivers) {
|
|
1774
|
+
let score = 0.15;
|
|
1775
|
+
if (input.governance.effectiveMode === 'standard')
|
|
1776
|
+
score += 0.1;
|
|
1777
|
+
if (input.governance.effectiveMode === 'expanded')
|
|
1778
|
+
score += 0.25;
|
|
1779
|
+
if (input.governance.effectiveMode === 'critical')
|
|
1780
|
+
score += 0.4;
|
|
1781
|
+
score += Math.min(0.2, input.files.length * 0.025);
|
|
1782
|
+
score += Math.min(0.2, gates.filter(gate => gate.required).length * 0.08);
|
|
1783
|
+
if (input.skillPlan.executionPlan.steps.some(step => step.required))
|
|
1784
|
+
score += 0.08;
|
|
1785
|
+
if (drivers.includes('explicit-uncertainty-language'))
|
|
1786
|
+
score += 0.12;
|
|
1787
|
+
return roundMetric(clampUnit(score));
|
|
1788
|
+
}
|
|
1789
|
+
function evaluatorRecommendations(gates, riskLevel) {
|
|
1790
|
+
if (gates.length === 0)
|
|
1791
|
+
return ['No evaluator gate required; keep lightweight verification evidence for low-risk work.'];
|
|
1792
|
+
const recommendations = ['Record evaluator evidence before promoting reasoning-heavy implementation or release claims.'];
|
|
1793
|
+
if (riskLevel === 'high')
|
|
1794
|
+
recommendations.push('Require reviewer sign-off for uncertainty, rejected alternatives, and rollback or mitigation path.');
|
|
1795
|
+
if (gates.some(gate => gate.id === 'root-cause-review'))
|
|
1796
|
+
recommendations.push('List competing root-cause hypotheses and why each was accepted or rejected.');
|
|
1797
|
+
if (gates.some(gate => gate.id === 'security-threat-model'))
|
|
1798
|
+
recommendations.push('Attach threat model or security-review evidence before guarded completion.');
|
|
1799
|
+
return recommendations;
|
|
1358
1800
|
}
|
|
1359
1801
|
function recommendations(options) {
|
|
1360
1802
|
const output = [];
|
|
@@ -1370,6 +1812,12 @@ function recommendations(options) {
|
|
|
1370
1812
|
if (options.governance.effectiveMode === 'critical') {
|
|
1371
1813
|
output.push('Critical workflow mode requires security review and rollback or disable strategy.');
|
|
1372
1814
|
}
|
|
1815
|
+
if (options.evaluator.required) {
|
|
1816
|
+
output.push(`Evaluator intelligence requires ${options.evaluator.gates.length} critique gate(s); record uncertainty and review evidence before promotion.`);
|
|
1817
|
+
}
|
|
1818
|
+
if (options.toolStrategy.summary.totalSteps > 0) {
|
|
1819
|
+
output.push(`Tool strategy planner created ${options.toolStrategy.summary.totalSteps} cost/retry/fallback node(s); execute required nodes with evidence.`);
|
|
1820
|
+
}
|
|
1373
1821
|
return output;
|
|
1374
1822
|
}
|
|
1375
1823
|
function normalizeSkillTaskLevel(value) {
|