@@ -324,6 +324,64 @@ def add(
324324 )
325325 self ._consequences .append (consequence )
326326
327+ def add_from_conversion_report (self , report : "ConversionReport" ) -> None :
328+ """Convert ConversionReport field operations to nested consequences.
329+
330+ Maps ConversionReport data to the unified consequence model:
331+ - report.operation → resource ConsequenceType
332+ - field_op "UPDATED" → ConsequenceType.UPDATE
333+ - field_op "UNSUPPORTED" → ConsequenceType.SKIP
334+ - field_op "UNCHANGED" → ConsequenceType.UNCHANGED
335+
336+ Reference: R06 §3.5 (06-dependency_analysis_v0.md)
337+ Reference: R04 §1.2 (04-reporting_infrastructure_coexistence_v0.md)
338+
339+ Args:
340+ report: ConversionReport with field operations to convert
341+
342+ Invariants:
343+ - All field operations become children of resource consequence
344+ - UNSUPPORTED fields include "(unsupported by host)" suffix
345+ """
346+ # Import here to avoid circular dependency
347+ from hatch .mcp_host_config .reporting import ConversionReport
348+
349+ # Map report.operation to resource ConsequenceType
350+ operation_map = {
351+ "create" : ConsequenceType .CONFIGURE ,
352+ "update" : ConsequenceType .CONFIGURE ,
353+ "delete" : ConsequenceType .REMOVE ,
354+ "migrate" : ConsequenceType .CONFIGURE ,
355+ }
356+ resource_type = operation_map .get (report .operation , ConsequenceType .CONFIGURE )
357+
358+ # Build resource message
359+ resource_message = f"Server '{ report .server_name } ' on '{ report .target_host .value } '"
360+
361+ # Map field operations to child consequences
362+ field_op_map = {
363+ "UPDATED" : ConsequenceType .UPDATE ,
364+ "UNSUPPORTED" : ConsequenceType .SKIP ,
365+ "UNCHANGED" : ConsequenceType .UNCHANGED ,
366+ }
367+
368+ children = []
369+ for field_op in report .field_operations :
370+ child_type = field_op_map .get (field_op .operation , ConsequenceType .UPDATE )
371+
372+ # Format field message based on operation type
373+ if field_op .operation == "UPDATED" :
374+ child_message = f"{ field_op .field_name } : { repr (field_op .old_value )} → { repr (field_op .new_value )} "
375+ elif field_op .operation == "UNSUPPORTED" :
376+ child_message = f"{ field_op .field_name } : (unsupported by host)"
377+ else : # UNCHANGED
378+ child_message = f"{ field_op .field_name } : { repr (field_op .new_value )} "
379+
380+ children .append (Consequence (type = child_type , message = child_message ))
381+
382+ # Add the resource consequence with children
383+ self .add (resource_type , resource_message , children = children )
384+
327385 def _format_consequence (
328386 self ,
329387 consequence : Consequence ,
0 commit comments