@@ -98,3 +98,49 @@ describe("ce-explain destination and handoff routing", () => {
9898 ) . toBe ( true )
9999 } )
100100} )
101+
102+ // Cross-file parity guard (issue #1057): SKILL.md Phase 3 and
103+ // references/check-in.md deliberately BOTH carry the predict-then-reveal
104+ // protocol — the inline copy is load-bearing (AGENTS.md: "Inline the Trigger,
105+ // Not the Content"; the routing test above guards its presence), and the
106+ // reference holds the on-demand detail. Two independently-editable copies of
107+ // a safety-critical protocol can drift silently, so each load-bearing
108+ // invariant must survive in both files. These are structural matches, not
109+ // verbatim prose locks — the two copies already word the protocol slightly
110+ // differently, and future wording improvements are fine as long as every
111+ // invariant stays present in both.
112+ describe ( "ce-explain predict-then-reveal parity between SKILL.md and references/check-in.md" , ( ) => {
113+ const CHECK_IN_PATH = path . join ( process . cwd ( ) , "skills/ce-explain/references/check-in.md" )
114+ const CHECK_IN_BODY = readFileSync ( CHECK_IN_PATH , "utf8" )
115+
116+ const invariants : { name : string ; pattern : RegExp } [ ] = [
117+ {
118+ name : "the prediction question (what the change does, and why it was made)" ,
119+ pattern : / w h a t d o (?: e s ) ? \s + (?: y o u t h i n k \s + ) ? t h i s c h a n g e d o (?: e s ) ? \b [ \s \S ] { 0 , 40 } ?w h y (?: w a s i t | i t w a s ) m a d e / i,
120+ } ,
121+ {
122+ name : "the turn-end rule (end the turn after the prediction prompt)" ,
123+ pattern : / e n d t h e t u r n / i,
124+ } ,
125+ {
126+ name : "the never-same-message rule (no explanation in the prediction-prompt message)" ,
127+ pattern : / s a m e m e s s a g e a s t h e p r e d i c t i o n p r o m p t / i,
128+ } ,
129+ ]
130+
131+ const copies : { label : string ; body : string } [ ] = [
132+ { label : "SKILL.md" , body : SKILL_BODY } ,
133+ { label : "references/check-in.md" , body : CHECK_IN_BODY } ,
134+ ]
135+
136+ for ( const { name, pattern } of invariants ) {
137+ for ( const { label, body } of copies ) {
138+ test ( `${ label } carries ${ name } ` , ( ) => {
139+ expect (
140+ pattern . test ( body ) ,
141+ `ce-explain ${ label } no longer carries ${ name } . The predict-then-reveal protocol is duplicated across SKILL.md and references/check-in.md by design; if the wording changed, keep the invariant present in BOTH copies (matching ${ pattern } ) so the copies cannot drift apart silently.` ,
142+ ) . toBe ( true )
143+ } )
144+ }
145+ }
146+ } )
0 commit comments