// evaluation-cmmi-engine.jsx — Verigo Global: CMMI v2.0 readiness evaluation engine // Target Maturity Level chosen in scope decides which practice areas are assessed. // Exposes window.EVAL_CMMI const { V: GV, MAXW: GMW, FONT: GFT } = window; // Build PA→icon lookup from CMMI_CATS global (loaded first by data file) const CMMI_PA_ICONS = {}; (function(){ CMMI_CATS.forEach(c => c.pas.forEach(p => { CMMI_PA_ICONS[p.code] = c.icon; })); })(); /* ── QUESTION BANK — 20 practice areas × 2 questions each ── */ const CMMI_Q = [ { code:'EST', name:'Estimating', ml2:true, docs:['Estimating & Planning Policy','Project Estimating Procedure'], q:[ ['EST 1.1','Estimates of work product size, effort, and cost are established and recorded.'],['EST 2.1','Estimates are reconciled with actual data and updated throughout the project.'], ]}, { code:'PLAN', name:'Planning', ml2:true, docs:['Estimating & Planning Policy','Project Planning Procedure'], q:[ ['PLAN 1.1','A project plan is established, documenting milestones, resources, and commitments.'],['PLAN 2.2','The plan is maintained and reconciled with available resources.'], ]}, { code:'MC', name:'Monitor and Control', ml2:true, docs:['Project Monitoring & Control Policy','Monitor & Control Procedure'], q:[ ['MC 1.1','Project performance is monitored against the plan at defined intervals.'],['MC 1.2','Corrective actions are taken and managed to closure when actual performance deviates from the plan.'], ]}, { code:'SAM', name:'Supplier Agreement Management', ml2:true, docs:['Supplier Agreement Management Policy','Supplier Evaluation & Agreement Procedure'], q:[ ['SAM 1.1','Formal supplier agreements define requirements, delivery, acceptance, and review criteria.'],['SAM 1.2','Supplier performance is monitored against agreements.'], ]}, { code:'RDM', name:'Requirements Development & Management', ml2:true, docs:['Requirements Management Policy','Requirements Development & Management Procedure'], q:[ ['RDM 1.1','Requirements are elicited, developed, analyzed, and recorded.'],['RDM 1.2','Requirements are traced bidirectionally throughout the project lifecycle.'], ]}, { code:'PQA', name:'Process Quality Assurance', ml2:true, docs:['Process Quality Assurance Policy','Quality Assurance Review Procedure'], q:[ ['PQA 1.1','Adherence of performed processes to applicable plans and standards is objectively evaluated.'],['PQA 2.1','Noncompliance issues are communicated and resolved.'], ]}, { code:'CM', name:'Configuration Management', ml2:true, docs:['Configuration Management Policy','Configuration Management Procedure'], q:[ ['CM 1.1','Configuration items are identified and baselines are established.'],['CM 2.1','Changes to configuration items are tracked and controlled; audits are conducted.'], ]}, { code:'MA', name:'Measurement and Analysis', ml2:true, docs:['Measurement & Analysis Policy','Measurement Data Collection Procedure'], q:[ ['MA 1.1','Measurement objectives and measures are established aligned to information needs.'],['MA 2.1','Measurement data is collected, stored, analyzed, and reported.'], ]}, { code:'GOV', name:'Governance', ml2:true, docs:['Process Management Policy'], q:[ ['GOV 1.1','Senior management commitment to CMMI processes is demonstrated and sustained.'],['GOV 1.2','Policies guide CMMI implementation across the organization.'], ]}, { code:'II', name:'Implementation Infrastructure', ml2:true, docs:['Process Management Policy'], q:[ ['II 1.1','Resources, roles, and repositories needed for process implementation are identified and provided.'],['II 2.1','Process support and guidance is accessible to practitioners.'], ]}, { code:'VV', name:'Verification and Validation', ml2:false, docs:['Verification & Validation Policy'], q:[ ['VV 1.1','Work products selected for verification are reviewed against requirements.'],['VV 2.2','Validation confirms that products meet their intended use in the target environment.'], ]}, { code:'TS', name:'Technical Solution', ml2:false, docs:['Technical Solution Policy'], q:[ ['TS 1.1','Technical solutions are selected and the product is designed to satisfy requirements.'],['TS 2.1','The design is implemented and integrated into a deliverable product or component.'], ]}, { code:'PI', name:'Product Integration', ml2:false, docs:['Process Management Policy'], q:[ ['PI 1.1','Product integration preparation ensures interface compatibility and integration sequences are defined.'],['PI 2.1','Product components are assembled and the integrated product is delivered.'], ]}, { code:'PR', name:'Peer Reviews', ml2:false, docs:['Peer Review Policy','Peer Review Procedure'], q:[ ['PR 1.1','Peer reviews are prepared with checklists, roles, and entry/exit criteria.'],['PR 2.1','Peer review data is analyzed and used to improve the work product and process.'], ]}, { code:'PCM', name:'Process Management', ml2:false, docs:['Process Management Policy'], q:[ ['PCM 1.1',"Organizational process needs are established and process performance baselines are maintained."],['PCM 2.2','The performance of the organization\'s processes is continuously monitored.'], ]}, { code:'OT', name:'Organizational Training', ml2:false, docs:['Process Management Policy'], q:[ ['OT 1.1','Skills needed for assigned roles are identified and training plans are established.'],['OT 2.1','Training effectiveness is assessed and training records are maintained.'], ]}, { code:'DAR', name:'Decision Analysis and Resolution', ml2:false, docs:['Decision Analysis & Resolution Policy'], q:[ ['DAR 1.1','Formal evaluation criteria are established for significant decisions.'],['DAR 2.1','Alternative solutions are evaluated against criteria and decisions are documented.'], ]}, { code:'RSK', name:'Risk and Opportunity Management', ml2:false, docs:['Risk & Opportunity Management Policy','Risk & Opportunity Management Procedure'], q:[ ['RSK 1.1','Risks are identified, categorized, and prioritized.'],['RSK 2.1','Risk mitigation plans are developed, implemented, and monitored.'], ]}, { code:'PAD', name:'Process Asset Development', ml2:false, docs:['Process Management Policy','Process Improvement Proposal Procedure'], q:[ ['PAD 1.1','Organizational process assets are established and maintained in a library.'],['PAD 2.1','Process improvement proposals are gathered, reviewed, and implemented.'], ]}, { code:'MPM', name:'Managing Performance and Measurement', ml2:false, docs:['Measurement & Analysis Policy'], q:[ ['MPM 1.1','Performance baselines and models are established to support quantitative management.'],['MPM 2.1','Performance data is used to manage selected processes quantitatively.'], ]}, { code:'CAR', name:'Causal Analysis and Resolution', ml2:false, docs:['Causal Analysis & Resolution Policy','Causal Analysis & Resolution Procedure'], q:[ ['CAR 1.1','Causes of defects and problems are identified and analyzed.'],['CAR 2.1','Corrective actions are implemented and their effect on process performance is evaluated.'], ]}, ]; const CMMI_ML_LABELS = { ml2:'ML2 · Managed', ml3:'ML3 · Defined', ml45:'ML4/5 · Quantitative' }; function mSectionsForML(ml) { const lv = (ml === 'ml2' || ml === 'ml3' || ml === 'ml45') ? ml : 'ml3'; const grp = CMMI_ML_LABELS[lv]; const list = lv === 'ml2' ? CMMI_Q.filter(p => p.ml2) : CMMI_Q; return list.map(p => ({ code: p.code, theme: p.code + ' · ' + p.name, group: grp, icon: CMMI_PA_ICONS[p.code] || 'layers', docs: p.docs, controls: (CMMI_CATS.find(c=>c.pas.find(pa=>pa.code===p.code))?.pas.find(pa=>pa.code===p.code)?.items.length||3), q: p.q })); } const COPTIONS = [['Not started',0],['Partial',1],['Largely',2],['Fully',3]]; const CBANDS = [ [0,'Initial',GV.orange,'Process activities are ad hoc — start with the ML2 essentials.'], [40,'Developing',GV.orange,'Some practices exist but key ML2 areas have gaps.'], [60,'Managed',GV.purple,'ML2 baseline is largely in place — focus on the remaining gaps.'], [80,'Defined',GV.purple,'Strong posture — formalize remaining practices and evidence for appraisal.'], ]; const cBandFor = pct => { let b=CBANDS[0]; CBANDS.forEach(x=>{ if(pct>=x[0]) b=x; }); return b; }; function mCompute(answers, sections) { const secs = sections || mSectionsForML('ml3'); const themes = secs.map((t,ti)=>{ const max=t.q.length*3; let sum=0; t.q.forEach((_,qi)=>{ sum+=(answers[ti+'-'+qi]||0); }); const pct=Math.round((sum/max)*100); return { theme:t.theme, code:t.code, group:t.group, icon:t.icon, docs:t.docs, controls:t.controls, pct, gaps:Math.round((1-pct/100)*t.controls) }; }); const overall=themes.length?Math.round(themes.reduce((a,t)=>a+t.pct,0)/themes.length):0; const totalControls=secs.reduce((a,t)=>a+t.controls,0); const gaps=themes.reduce((a,t)=>a+t.gaps,0); return { themes, overall, gaps, totalControls, level:(secs[0]&&secs[0].group)||CMMI_ML_LABELS.ml3, band:cBandFor(overall) }; } /* ── SEGMENTED ────────────────────────────────────────────── */ const MSegmented = ({ value, onChange }) => (
{COPTIONS.map(([label,val])=>{ const on=value===val; return ; })}
); /* ── QUIZ ────────────────────────────────────────────────── */ const EvalQuizCMMI = ({ onComplete, onExit, ml, initialAnswers, initialStep, onProgress }) => { const sections = React.useMemo(()=>mSectionsForML(ml),[ml]); const [step,setStep] = React.useState(()=>Math.min(Math.max(initialStep||0,0),sections.length-1)); const [answers,setAnswers] = React.useState(()=>initialAnswers||{}); const total=sections.length; const cur=sections[step]; const report=(a,s)=>{ if(onProgress) onProgress(a,s); }; const set=(qi,v)=>setAnswers(a=>{ const na={...a,[step+'-'+qi]:v}; report(na,step); return na; }); const stepDone=cur.q.every((_,qi)=>answers[step+'-'+qi]!==undefined); const answeredCount=Object.keys(answers).length; const totalQ=sections.reduce((a,t)=>a+t.q.length,0); const progress=Math.round((answeredCount/totalQ)*100); const next=()=>{ if(step{ if(step>0){const ns=step-1;setStep(ns);report(answers,ns);window.scrollTo({top:0});}else{onExit();} }; return (
Practice area {step+1} of {total} {progress}% complete
{cur.group}

{cur.theme}

For each statement, choose how completely it reflects your organization today. Each maps to a specific CMMI v2.0 practice.

{cur.q.map(([code,text],qi)=>(
{code}

{text}

set(qi,v)} />
))}
{step===0?'Exit':'Back'} {step===total-1?'See my results':'Next practice area'}
{!stepDone&&

Answer all {cur.q.length} statements to continue.

}
Your progress is saved automatically — you can leave and resume later.
); }; /* ── RESULTS ─────────────────────────────────────────────── */ const MDonut = ({ pct }) => (
{pct} / 100
); const EvalResultsCMMI = ({ results, user, onNav, onRetake }) => { const { themes, overall, gaps, band, totalControls, level } = results; const [,label,,bandDesc] = band; const sorted = [...themes].sort((a,b)=>a.pct-b.pct); const focus = sorted.filter(t=>t.pct<80); const MODULES = window.TK_CMMI.QUOTE_MODULES; const reco = new Set(['tailor']); if (overall<80) reco.add('guidance'); if (overall<60) { reco.add('impl'); reco.add('appraisal'); } themes.forEach(t=>{ if(t.pct<60&&(t.code==='MA'||t.code==='GOV'||t.code==='PCM')) reco.add('workshop'); }); const recoModules = MODULES.filter(m=>reco.has(m.id)); const goBuild = () => { try{localStorage.setItem('verigo_reco_cmmi',JSON.stringify([...reco]));}catch(e){} onNav('checkout'); }; return (
Your readiness report · {level}
Overall maturity · {label}

{overall>=80?"You're close to appraisal-ready.":overall>=60?"A solid base, with clear gaps to close.":"There's real groundwork to do first."}

{bandDesc} We estimate ~{gaps} of {totalControls} practices need attention before your appraisal.{user&&user.company?' Prepared for '+user.company:''}

{themes.map((t,i)=>{ const c=t.pct<60?GV.orange:GV.purple; return(
{t.theme} {t.pct}%
~{t.gaps} of {t.controls} practices need attention
); })}
{focus.length===0&&(
Every practice area scored 80%+ — you're in strong shape. A practitioner can help validate evidence and prepare for appraisal.
)} {focus.map((t,i)=>(
{i+1}

{t.theme}

{t.pct}%
{t.docs.map((d,di)=>({d}))}
onNav('toolkit:cmmi')} style={{whiteSpace:'nowrap'}}>Open toolkit
))}
window.EVAL_CMMI.generateEvalPDF(results,user)}> Download my results (PDF) Retake the evaluation
{recoModules.map((m,i)=>(
{m.name}
{m.desc}
))}
Build my custom package Pick your options, see the price, then download a custom quote.
); }; /* ── RESULTS PDF ──────────────────────────────────────────── */ function genEvalPDFCMMI(results, user) { const lib=window.jspdf; if(!lib||!lib.jsPDF){alert('PDF engine is still loading.');return;} const {themes,overall,gaps,band,totalControls,level}=results; const doc=new lib.jsPDF({unit:'pt',format:'a4'}); const W=doc.internal.pageSize.getWidth(); const H=doc.internal.pageSize.getHeight(); const M=50; const PURPLE=[91,46,145],ORANGE=[232,98,42],INK=[30,30,46],GREY=[120,120,134]; let y=100; doc.setFillColor(...PURPLE);doc.rect(0,0,W,70,'F');doc.setFillColor(...ORANGE);doc.rect(W-M-11,28,11,11,'F');doc.setTextColor(255,255,255);doc.setFont('helvetica','bold');doc.setFontSize(15);doc.text('VERIGO GLOBAL',M,33);doc.setFont('helvetica','normal');doc.setFontSize(8.5);doc.setTextColor(214,204,232);doc.text('Compliance by Design',M,49);doc.setTextColor(255,255,255);doc.setFontSize(8.5);doc.text('CMMI v2.0',W-M-20,35,{align:'right'}); doc.setTextColor(...INK);doc.setFont('helvetica','bold');doc.setFontSize(21);doc.text('CMMI v2.0 Readiness Report',M,y);y+=12; doc.setDrawColor(...ORANGE);doc.setLineWidth(2.5);doc.line(M,y,M+54,y);y+=16; doc.setFont('helvetica','normal');doc.setFontSize(10);doc.setTextColor(...GREY);doc.text(String(level||''),M,y);y+=18; doc.setFont('helvetica','bold');doc.setFontSize(40);doc.setTextColor(...PURPLE);doc.text(String(overall),M,y+14);doc.setFontSize(11);doc.setTextColor(...GREY);doc.setFont('helvetica','normal');doc.text('/ 100',M+58,y+14);doc.setFont('helvetica','bold');doc.setFontSize(13);doc.setTextColor(...INK);doc.text('Overall maturity: '+band[1],M+130,y-2);doc.setFont('helvetica','normal');doc.setFontSize(10);doc.setTextColor(...GREY);doc.splitTextToSize('~'+gaps+' of '+(totalControls||60)+' practices need attention. '+band[3],W-M-(M+130)).forEach((ln,i)=>doc.text(ln,M+130,y+14+i*13));y+=56; if(user&&(user.company||user.name)){doc.setDrawColor(224,224,232);doc.setLineWidth(0.5);doc.line(M,y,W-M,y);y+=16;doc.setFontSize(9);doc.setTextColor(...PURPLE);doc.setFont('helvetica','bold');doc.text('Prepared for '+(user.company||user.name),M,y);doc.setFont('helvetica','normal');doc.setTextColor(...GREY);doc.text(new Date().toLocaleDateString('en-US',{year:'numeric',month:'long',day:'numeric'}),W-M,y,{align:'right'});y+=22;} doc.setFont('helvetica','bold');doc.setFontSize(12.5);doc.setTextColor(...PURPLE);doc.text('Maturity by practice area',M,y);y+=6;doc.setDrawColor(...PURPLE);doc.setLineWidth(0.8);doc.line(M,y,W-M,y);y+=20; const barX=M+220,barW=W-M-barX; themes.forEach(t=>{if(y>H-70){doc.addPage();y=60;}doc.setFont('helvetica','bold');doc.setFontSize(9.5);doc.setTextColor(...INK);doc.splitTextToSize(t.theme,200).forEach((ln,i)=>doc.text(ln,M,y+3+i*10));doc.setFillColor(237,237,245);doc.rect(barX,y-7,barW,10,'F');const col=t.pct<60?ORANGE:PURPLE;doc.setFillColor(...col);doc.rect(barX,y-7,barW*(t.pct/100),10,'F');doc.setFont('helvetica','bold');doc.setFontSize(10);doc.setTextColor(...col);doc.text(t.pct+'%',W-M,y+3,{align:'right'});y+=24;}); const focus=[...themes].sort((a,b)=>a.pct-b.pct).filter(t=>t.pct<80); if(focus.length){if(y>H-90){doc.addPage();y=60;}doc.setFont('helvetica','bold');doc.setFontSize(12.5);doc.setTextColor(...PURPLE);doc.text('Recommended next steps',M,y);y+=6;doc.setDrawColor(...PURPLE);doc.setLineWidth(0.8);doc.line(M,y,W-M,y);y+=18;focus.forEach((t,i)=>{if(y>H-90){doc.addPage();y=60;}doc.setFont('helvetica','bold');doc.setFontSize(10.5);doc.setTextColor(...INK);doc.text((i+1)+'. '+t.theme+' ('+t.pct+'%)',M,y);y+=14;doc.setFont('helvetica','normal');doc.setFontSize(9.5);doc.setTextColor(...GREY);doc.splitTextToSize('Toolkit documents: '+t.docs.join(', '),W-2*M-14).forEach(ln=>{doc.text(ln,M+14,y);y+=12;});y+=8;});} const total=doc.internal.getNumberOfPages();for(let i=1;i<=total;i++){doc.setPage(i);doc.setDrawColor(224,224,232);doc.setLineWidth(0.5);doc.line(M,H-38,W-M,H-38);doc.setFont('helvetica','normal');doc.setFontSize(8);doc.setTextColor(150,150,160);doc.text('© 2026 Verigo Global · Readiness self-assessment — indicative, not a formal appraisal',M,H-24);doc.text(i+' / '+total,W-M,H-24,{align:'right'});} doc.save('Verigo-CMMI-Readiness-Report.pdf'); } window.EVAL_CMMI = { QUESTIONS:CMMI_Q, sectionsForML:mSectionsForML, computeResults:mCompute, EvalQuiz:EvalQuizCMMI, EvalResults:EvalResultsCMMI, generateEvalPDF:genEvalPDFCMMI }; Object.assign(window, { EvalQuizCMMI, EvalResultsCMMI });