@@ -106,6 +106,21 @@ function createWorkspaceNamespaceWorkspace(projectInfo) {
106106 return root
107107}
108108
109+ function createClosedLoopWorkspaceNamespace ( projectInfo ) {
110+ const root = createWorkspaceNamespaceWorkspace ( projectInfo )
111+ writeFile ( root , '.devcodex/workspace/profile/README.md' , [
112+ '# README' ,
113+ '' ,
114+ '- Profile 档位:profile-closed-loop。' ,
115+ '- 生命周期:01~03 为稳定基线;04~07 为活文档;config.local.json 与 08+ 为条件 / 本地文档。'
116+ ] . join ( '\n' ) )
117+ writeFile ( root , '.devcodex/workspace/profile/04-测试规范.md' , '# 04 — 测试规范\n' )
118+ writeFile ( root , '.devcodex/workspace/profile/05-发布规范.md' , '# 05 — 发布规范\n' )
119+ writeFile ( root , '.devcodex/workspace/profile/06-功能清单.md' , featureInventoryDocument ( ) )
120+ writeFile ( root , '.devcodex/workspace/profile/07-用户文档与契约规范.md' , '# 07 — 用户文档与契约规范\n' )
121+ return root
122+ }
123+
109124function legacyProjectInfo ( ) {
110125 return [
111126 '# 01 — 项目信息' ,
@@ -174,6 +189,22 @@ function currentProjectInfo() {
174189 ] . join ( '\n' )
175190}
176191
192+ function createClosedLoopWorkspace ( lifecycle , readmeExtras = [ ] ) {
193+ const root = createWorkspace ( currentProjectInfo ( ) )
194+ writeFile ( root , '.devcodex/profile/README.md' , [
195+ '# README' ,
196+ '' ,
197+ '- Profile 档位:profile-closed-loop。' ,
198+ `- 生命周期:${ lifecycle } 。` ,
199+ ...readmeExtras
200+ ] . join ( '\n' ) )
201+ writeFile ( root , '.devcodex/profile/04-测试规范.md' , '# 04 — 测试规范\n' )
202+ writeFile ( root , '.devcodex/profile/05-发布规范.md' , '# 05 — 发布规范\n' )
203+ writeFile ( root , '.devcodex/profile/06-功能清单.md' , featureInventoryDocument ( ) )
204+ writeFile ( root , '.devcodex/profile/07-用户文档与契约规范.md' , '# 07 — 用户文档与契约规范\n' )
205+ return root
206+ }
207+
177208function validLocalConfig ( ) {
178209 return JSON . stringify ( {
179210 connections : {
@@ -424,6 +455,48 @@ function main() {
424455
425456 assert . strictEqual ( closedLoopResult . status , 0 , closedLoopOutput )
426457
458+ const closedLoopChineseRoot = createClosedLoopWorkspace ( '01~03 为稳定基线;04~07 为活文档;config.local.json 与 08+ 为条件 / 本地文档' )
459+ const closedLoopChineseResult = runValidate ( closedLoopChineseRoot )
460+ assert . strictEqual (
461+ closedLoopChineseResult . status ,
462+ 0 ,
463+ `${ closedLoopChineseResult . stdout } \n${ closedLoopChineseResult . stderr } `
464+ )
465+
466+ const lifecycleDiagnosticCases = [
467+ {
468+ name : 'stable-baseline' ,
469+ lifecycle : 'living document / conditional-required local docs' ,
470+ expected : 'stable-baseline'
471+ } ,
472+ {
473+ name : 'living-document' ,
474+ lifecycle : 'stable baseline / conditional-required local docs' ,
475+ expected : 'living-document'
476+ } ,
477+ {
478+ name : 'conditional-or-local-docs' ,
479+ lifecycle : 'stable baseline / living document' ,
480+ extras : [
481+ '- 本地命令:npm test。' ,
482+ '- required checks remain enabled。' ,
483+ '- conditional workflows are documented elsewhere。'
484+ ] ,
485+ expected : 'conditional-or-local-docs'
486+ }
487+ ]
488+ for ( const diagnosticCase of lifecycleDiagnosticCases ) {
489+ const diagnosticRoot = createClosedLoopWorkspace ( diagnosticCase . lifecycle , diagnosticCase . extras )
490+ const diagnosticResult = runValidate ( diagnosticRoot )
491+ const diagnosticOutput = `${ diagnosticResult . stdout } \n${ diagnosticResult . stderr } `
492+ assert . strictEqual ( diagnosticResult . status , 1 , `${ diagnosticCase . name } : ${ diagnosticOutput } ` )
493+ assert . match ( diagnosticOutput , new RegExp ( `lifecycle missing ${ diagnosticCase . expected } ` ) )
494+ for ( const category of [ 'stable-baseline' , 'living-document' , 'conditional-or-local-docs' ] ) {
495+ if ( category === diagnosticCase . expected ) continue
496+ assert . doesNotMatch ( diagnosticOutput , new RegExp ( `lifecycle missing ${ category } ` ) )
497+ }
498+ }
499+
427500 const missingColumnsRoot = createWorkspace ( currentProjectInfo ( ) )
428501 writeFile ( missingColumnsRoot , '.devcodex/profile/README.md' , '# README\n\n- Profile 档位:profile-closed-loop。\n- 生命周期:stable baseline / living document / conditional-required local docs。\n' )
429502 writeFile ( missingColumnsRoot , '.devcodex/profile/04-测试规范.md' , '# 04\n' )
@@ -677,6 +750,22 @@ function main() {
677750 assert . strictEqual ( explicitFallbackResult . status , 0 , explicitFallbackOutput )
678751 assert . doesNotMatch ( explicitFallbackOutput , / m i s s i n g r e q u i r e d / )
679752
753+ const closedLoopFallbackRoot = createClosedLoopWorkspaceNamespace ( currentProjectInfo ( ) )
754+ const closedLoopFallbackProfileDir = path . join ( closedLoopFallbackRoot , '.devcodex' , 'chat' , 'profile' )
755+ writeFile ( closedLoopFallbackRoot , '.devcodex/chat/profile/01-项目信息.md' , currentProjectInfo ( ) )
756+ const closedLoopFallbackResult = runValidateWithArgs (
757+ path . join ( closedLoopFallbackRoot , 'chat' ) ,
758+ [
759+ '--profile-dir' ,
760+ closedLoopFallbackProfileDir ,
761+ '--workspace-profile' ,
762+ path . join ( closedLoopFallbackRoot , '.devcodex' , 'workspace' , 'profile' )
763+ ]
764+ )
765+ const closedLoopFallbackOutput = `${ closedLoopFallbackResult . stdout } \n${ closedLoopFallbackResult . stderr } `
766+ assert . strictEqual ( closedLoopFallbackResult . status , 0 , closedLoopFallbackOutput )
767+ assert . doesNotMatch ( closedLoopFallbackOutput , / l i f e c y c l e m i s s i n g / )
768+
680769 const localTierOverridesFallbackRoot = createWorkspaceNamespaceWorkspace ( currentProjectInfo ( ) )
681770 const localStandardProfileDir = path . join ( localTierOverridesFallbackRoot , '.devcodex' , 'sample' , 'profile' )
682771 writeFile ( localTierOverridesFallbackRoot , '.devcodex/sample/profile/01-项目信息.md' , [
0 commit comments