@@ -387,6 +387,34 @@ assert.strictEqual(v2Decision.budget.selected.bytes,
387387assert . strictEqual ( v2Decision . budget . tokens . status , 'N/A' )
388388assert . deepStrictEqual ( v2Decision . writes , [ ] )
389389
390+ const missingResolutionRoot = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'devcodex-portfolio-resolution-' ) )
391+ try {
392+ const missingResolutionEnv = {
393+ HOME : path . join ( missingResolutionRoot , 'home' ) ,
394+ USERPROFILE : path . join ( missingResolutionRoot , 'home' ) ,
395+ DEVCODEX_GLOBAL_SKILLS_ROOT : path . join ( missingResolutionRoot , 'empty-global-skills' )
396+ }
397+ const packageFallbackDecision = buildBundleDecisionV2 ( first , {
398+ candidateIds : [ 'dev-testing' ] ,
399+ maxBytes : 1024 * 1024 ,
400+ cwd : missingResolutionRoot ,
401+ env : missingResolutionEnv
402+ } )
403+ assert . strictEqual ( packageFallbackDecision . completion , 'complete' )
404+ assert ( packageFallbackDecision . selected . every ( item => item . selectedLayer === 'package' ) )
405+ const requiredResolutionDecision = buildBundleDecisionV2 ( first , {
406+ candidateIds : [ 'dev-testing' ] ,
407+ maxBytes : 1024 * 1024 ,
408+ cwd : missingResolutionRoot ,
409+ env : missingResolutionEnv ,
410+ requireResolvedSkills : true
411+ } )
412+ assert . strictEqual ( requiredResolutionDecision . completion , 'blocked' )
413+ assert ( requiredResolutionDecision . blockers . some ( item => item . code === 'skill-resolution-missing' ) )
414+ } finally {
415+ fs . rmSync ( missingResolutionRoot , { recursive : true , force : true } )
416+ }
417+
390418const overBudgetMandatory = buildBundleDecisionV2 ( first , {
391419 candidateIds : [ 'dev-testing' ] ,
392420 maxSkills : 1 ,
0 commit comments