@@ -85,6 +85,50 @@ describe('Skill/Agent Discovery Completeness', () => {
8585 } ) ;
8686 } ) ;
8787
88+ describe ( 'core skill regression guard' , ( ) => {
89+ /**
90+ * Core skills that MUST always be discoverable.
91+ * If any of these disappear from discovery results, it indicates
92+ * a schema or parser regression that silently hides runtime skills.
93+ */
94+ const REQUIRED_CORE_SKILLS = [
95+ 'pr-review' ,
96+ 'systematic-debugging' ,
97+ 'database-migration' ,
98+ 'security-audit' ,
99+ ] as const ;
100+
101+ /**
102+ * Minimum number of skills that must be visible.
103+ * Prevents mass disappearance due to parser/schema changes.
104+ * Update this floor when skills are intentionally removed.
105+ */
106+ const MINIMUM_VISIBLE_SKILL_COUNT = 20 ;
107+
108+ it ( 'should include all required core skills in discovery results' , async ( ) => {
109+ const mcpSkills = await listSkillSummaries ( RULES_DIR ) ;
110+ const discoveredNames = new Set ( mcpSkills . map ( s => s . name ) ) ;
111+
112+ const missing = REQUIRED_CORE_SKILLS . filter ( name => ! discoveredNames . has ( name ) ) ;
113+
114+ expect (
115+ missing ,
116+ `Core skills missing from discovery: ${ missing . join ( ', ' ) } . ` +
117+ 'This likely indicates a schema or parser regression.' ,
118+ ) . toEqual ( [ ] ) ;
119+ } ) ;
120+
121+ it ( 'should not drop below minimum visible skill count' , async ( ) => {
122+ const mcpSkills = await listSkillSummaries ( RULES_DIR ) ;
123+
124+ expect (
125+ mcpSkills . length ,
126+ `Only ${ mcpSkills . length } skills visible (minimum: ${ MINIMUM_VISIBLE_SKILL_COUNT } ). ` +
127+ 'A sudden drop suggests a parser or schema change silently removed skills.' ,
128+ ) . toBeGreaterThanOrEqual ( MINIMUM_VISIBLE_SKILL_COUNT ) ;
129+ } ) ;
130+ } ) ;
131+
88132 describe ( 'SKILL_KEYWORDS orphan check' , ( ) => {
89133 it ( 'no orphaned keywords.ts entries — every skillName must exist on disk' , async ( ) => {
90134 const skillsDir = path . join ( RULES_DIR , 'skills' ) ;
0 commit comments