@@ -124,6 +124,32 @@ describe("CommandPlugin.Plugin", () => {
124124 } ) ,
125125 )
126126
127+ it . effect ( "publishes an exact block YAML authoring contract" , ( ) =>
128+ Effect . sync ( ( ) => {
129+ expect ( CommandPlugin . WorkflowBlocksContent ) . toContain ( "Never infer or invent a YAML field" )
130+ expect ( CommandPlugin . WorkflowBlocksContent ) . toContain ( "### Start file" )
131+ expect ( CommandPlugin . WorkflowBlocksContent ) . toContain ( "### Extend file" )
132+ expect ( CommandPlugin . WorkflowBlocksContent ) . toContain ( "### Replan file" )
133+ expect ( CommandPlugin . WorkflowBlocksContent ) . toMatch (
134+ / ` i d ` , ` k i n d ` , ` d e p e n d s _ o n ` , ` i n s t r u c t i o n ` , \s + ` w o r k e r _ t y p e ` , ` r e q u i r e d ` , a n d ` r e p o r t _ t o _ p a r e n t ` / ,
135+ )
136+ expect ( CommandPlugin . WorkflowBlocksContent ) . toMatch (
137+ / ` a c t i o n ` , ` w o r k f l o w _ i d ` , ` o p e r a t i o n ` , a n d ` s p e c _ p a t h ` a r e t o o l - c a l l f i e l d s / ,
138+ )
139+ const authoringContract = CommandPlugin . WorkflowBlocksContent . slice (
140+ CommandPlugin . WorkflowBlocksContent . indexOf ( "## Authoring contract" ) ,
141+ CommandPlugin . WorkflowBlocksContent . indexOf ( "This guide owns" ) ,
142+ )
143+ expect ( authoringContract ) . toMatch ( / [ T t ] h e \s + l i s t e d Y A M L f i e l d s a r e e x h a u s t i v e / )
144+ expect ( authoringContract ) . not . toMatch (
145+ / s e s s i o n _ i d | p r o j e c t _ i d | p r o t o c o l _ v e r s i o n | f i n g e r p r i n t | n o d e _ d e f a u l t s \. m o d e l | n o d e \. m o d e l / ,
146+ )
147+ expect ( CommandPlugin . WorkflowBlocksContent ) . toContain (
148+ '{ action: "control", operation: "replan", workflow_id: "dag_...", spec_path: "replan.yaml" }' ,
149+ )
150+ } ) ,
151+ )
152+
127153 it . effect ( "preserves opt-outs read-only scope and explicit role assignments" , ( ) =>
128154 Effect . sync ( ( ) => {
129155 expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain ( "single agent" )
@@ -137,9 +163,7 @@ describe("CommandPlugin.Plugin", () => {
137163
138164 it . effect ( "documents config-first model fallback without invented identifiers" , ( ) =>
139165 Effect . sync ( ( ) => {
140- expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain (
141- "Never emit `node.model` or `config.node_defaults.model`" ,
142- )
166+ expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain ( "Workflow YAML has no model-selection field" )
143167 expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain (
144168 "`dag.jsonc` tier → configured agent model → parent session model" ,
145169 )
@@ -338,14 +362,17 @@ describe("CommandPlugin.Plugin", () => {
338362 expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain ( "waiver_reason" )
339363 expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain ( "acknowledged_risks" )
340364 expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain ( "Material changes" )
341- expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain ( "invalidate the prior fingerprint " )
342- expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain ( "SHA-256 hash" )
343- expect ( CommandPlugin . WorkflowFactsContent ) . toContain (
344- "The start spec places `mode: deep`, a versioned `READY` or informed `WAIVED`" ,
365+ expect ( CommandPlugin . OrchestrationPolicyContent ) . toContain ( "invalidate the prior admission record " )
366+ const admissionPolicy = CommandPlugin . OrchestrationPolicyContent . slice (
367+ CommandPlugin . OrchestrationPolicyContent . indexOf ( "## Deep Admission QA" ) ,
368+ CommandPlugin . OrchestrationPolicyContent . indexOf ( "## Role Resolution" ) ,
345369 )
370+ expect ( admissionPolicy ) . not . toMatch ( / p r o t o c o l _ v e r s i o n | f i n g e r p r i n t / )
346371 expect ( CommandPlugin . WorkflowFactsContent ) . toContain (
347- "the workflow boundary owns `protocol_version `, `state`, and\n`fingerprint `" ,
372+ "The start spec places `mode: deep `, a versioned `READY` or informed `WAIVED `" ,
348373 )
374+ expect ( CommandPlugin . WorkflowFactsContent ) . toContain ( "The admission input accepts\nonly `brief_revision`" )
375+ expect ( CommandPlugin . WorkflowFactsContent ) . not . toMatch ( / p r o t o c o l _ v e r s i o n | n o d e _ d e f a u l t s \. m o d e l | n o d e \. m o d e l / )
349376 expect ( CommandPlugin . WorkflowFactsContent ) . toContain ( "A one-off graph may use a" )
350377 expect ( CommandPlugin . WorkflowFactsContent ) . toContain ( "task-local file" )
351378 expect ( CommandPlugin . WorkflowFactsContent ) . not . toContain ( "`config.mode`" )
@@ -388,11 +415,9 @@ describe("CommandPlugin.Plugin", () => {
388415 expect ( CommandPlugin . WorkflowFactsContent ) . not . toContain ( "Gate failure cancels the workflow automatically" )
389416 expect ( CommandPlugin . WorkflowFactsContent ) . toContain ( "Static `prompt_template.input`" )
390417 expect ( CommandPlugin . WorkflowFactsContent ) . toContain ( "it must\nnever appear as `[object Object]`" )
391- expect ( CommandPlugin . WorkflowFactsContent ) . toContain (
392- "Workflow definitions MUST NOT specify `node.model` or\n`config.node_defaults.model`" ,
393- )
418+ expect ( CommandPlugin . WorkflowFactsContent ) . toContain ( "Workflow YAML has no model-selection field" )
394419 expect ( CommandPlugin . WorkflowFactsContent ) . toMatch (
395- / ` d a g \. j s o n c ` t i e r , t h e n t h e \s + c o n f i g u r e d a g e n t m o d e l , t h e n t h e p a r e n t - s e s s i o n m o d e l / ,
420+ / ` d a g \. j s o n c ` \s + t i e r , t h e n t h e \s + c o n f i g u r e d a g e n t m o d e l , t h e n t h e p a r e n t - s e s s i o n m o d e l / ,
396421 )
397422 expect ( CommandPlugin . WorkflowFactsContent ) . toContain ( "Propose-then-assemble" )
398423 const reviewExample = CommandPlugin . WorkflowFactsContent . slice (
0 commit comments