Feature: Structural component output validation

    Output validation checks structural components (not exact characters).
    Required fields are validated for presence and correct type.
    Structural relationships are validated (parent-child, ordering).
    Minor formatting differences do not cause validation failures.
    Validation failures produce actionable error messages.

    Based on Epic #8137 - structural output validation overhaul.

    Scenario: validate_plan_tree accepts valid node count of 1
        Given the plan tree contains 1 node(s)
        When I validate the plan tree
        Then it should be structurally valid
        And it should report no errors

    Scenario: validate_plan_tree accepts valid node count of 5
        Given the plan tree contains 5 node(s)
        When I validate the plan tree
        Then it should be structurally valid
        And it should report no errors

    Scenario: validate_plan_tree accepts valid node count of 20
        Given the plan tree contains 20 node(s)
        When I validate the plan tree
        Then it should be structurally valid
        And it should report no errors

    Scenario: validate_plan_tree rejects nodes missing required keys
        Given the plan tree contains a node missing "decision_id"
        When I validate the plan tree
        Then it should be structurally invalid
        And it should report errors including "missing required key(s)"

    Scenario: validate_plan_tree rejects invalid ULID in decision_id
        Given the plan tree contains a node with invalid ULID "not-a-ulid-12345"
        When I validate the plan tree
        Then it should be structurally invalid
        And it should report errors including "must be a valid ULID"

    Scenario: validate_plan_tree accepts empty children list
        Given the plan tree contains a node with empty "children" list
        When I validate the plan tree
        Then it should be structurally valid

    Scenario: validate_plan_tree rejects duplicate sequences for siblings
        Given two sibling nodes share the same sequence number
        When I validate the plan tree
        Then it should be structurally invalid
        And it should report errors including "duplicate sequence"

    Scenario: validate_plan_tree accepts non-negative sequence 0
        Given a plan tree node with sequence "0"
        When I validate the plan tree
        Then it should be structurally valid

    Scenario: validate_plan_tree accepts non-negative sequence 1
        Given a plan tree node with sequence "1"
        When I validate the plan tree
        Then it should be structurally valid

    Scenario: validate_plan_tree accepts non-negative sequence 100
        Given a plan tree node with sequence "100"
        When I validate the plan tree
        Then it should be structurally valid

    Scenario: validate_plan_tree rejects negative sequence
        Given a plan tree node with sequence "-1"
        When I validate the plan tree
        Then it should be structurally invalid
        And error message must include "must be a non-negative integer"

    Scenario: validate_decision_dict accepts valid CLI dict for decision_id field
        Given I have a decision dict with "decision_id" set to 01ARZ3NDEKTSV4XXFFJFRC889A
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for plan_id field
        Given I have a decision dict with "plan_id" set to 01ARZ3NDEKTSV4XXFFJFRC889B
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for type field
        Given I have a decision dict with "type" set to strategy_choice
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for sequence field
        Given I have a decision dict with "sequence" set to 5
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for question field
        Given I have a decision dict with "question" set to Which approach?
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for chosen field
        Given I have a decision dict with "chosen" set to A
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for confidence field
        Given I have a decision dict with "confidence" set to 0.75
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for parent field
        Given I have a decision dict with "parent" set to (root)
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for is_correction field
        Given I have a decision dict with "is_correction" set to false
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict accepts valid CLI dict for superseded field
        Given I have a decision dict with "superseded" set to false
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict rejects confidence outside [0,1]
        Given I have a decision dict with "confidence" set to 1.5
        When I validate the decision dict
        Then it should be structurally invalid
        And error message must include "must be in range [0.0, 1.0]"

    Scenario: validate_decision_dict accepts None confidence
        Given I have a decision dict with "confidence" set to null
        When I validate the decision dict
        Then it should be structurally valid

    Scenario: validate_decision_dict rejects non-string question
        Given I have a decision dict with "question" set to 42
        When I validate the decision dict
        Then it should be structurally invalid
        And error message must include "must be a non-empty string"

    Scenario: validate_decision_dict rejects parent that is neither ULID nor "(root)"
        Given I have a decision dict with "parent" set to "random-string"
        When I validate the decision dict
        Then it should be structurally invalid
        And error message must include "must be a ULID or '(root)'"

    Scenario: validate_decision_dict rejects is_correction that is not boolean
        Given I have a decision dict with "is_correction" set to "yes"
        When I validate the decision dict
        Then it should be structurally invalid
        And error message must include "must be a boolean"

    Scenario: validate_structured_output accepts valid envelope for command field
        Given I have a structured output with "command" set to agents plan list (and all other required fields present)
        When I validate the structured output
        Then it should be structurally valid

    Scenario: validate_structured_output accepts valid envelope for session_id field
        Given I have a structured output with "session_id" set to 01ARZ3NDEKTSV4XXFFJFRC889A (and all other required fields present)
        When I validate the structured output
        Then it should be structurally valid

    Scenario: validate_structured_output accepts valid envelope for status field
        Given I have a structured output with "status" set to ok (and all other required fields present)
        When I validate the structured output
        Then it should be structurally valid

    Scenario: validate_structured_output accepts valid envelope for exit_code field
        Given I have a structured output with "exit_code" set to 0 (and all other required fields present)
        When I validate the structured output
        Then it should be structurally valid

    Scenario: validate_structured_output rejects invalid status value
        Given I have a structured output with "status" set to "running" (and all other required fields present)
        When I validate the structured output
        Then it should be structurally invalid
        And error must include "must be one of"

    Scenario: validate_structured_output rejects negative exit_code
        Given I have a structured output with "exit_code" set to "-1" (and all other required fields present)
        When I validate the structured output
        Then it should be structurally invalid
        And error must include "must be >= 0"

    Scenario: validate_structured_output accepts zero elements list
        Given I have a structured output with empty "elements" list (and all other fields valid)
        When I validate the structured output
        Then it should be structurally valid

    Scenario: validate_structured_output rejects invalid element format
        Given I have a structured output with an element missing "kind" field
        When I validate the structured output
        Then it should be structurally invalid
        And error must include "missing 'kind' field"

    Scenario: validate_structured_component_output routes plan_tree to correct validator
        Given I target validation for "plan_tree" with valid data
        When I call validate_structured_component_output
        Then it should dispatch to the matching validator
        And return a valid result

    Scenario: validate_structured_component_output routes decision to correct validator
        Given I target validation for "decision" with valid data
        When I call validate_structured_component_output
        Then it should dispatch to the matching validator
        And return a valid result

    Scenario: validate_structured_component_output routes structured_output to correct validator
        Given I target validation for "structured_output" with valid data
        When I call validate_structured_component_output
        Then it should dispatch to the matching validator
        And return a valid result

    Scenario: validate_structured_component_output rejects unknown target type
        Given I target validation for "unknown_type" with valid data
        When I call validate_structured_component_output
        Then it should raise a ValidationError with message containing "Unknown target_type"

    Scenario: Structural output is robust to minor formatting differences
        Given I have a decision dict where whitespace may vary between fields
        When I validate the decision dict
        Then validation should pass (structure matched, not exact characters)

    Scenario: Plan tree nodes preserve parent-child structural relationships
        Given a plan tree with parent and child node references connected by ULID
        When I validate the plan tree structure
        Then parent-child relationships should be validly connected

    Scenario: Validation error messages are actionable
        Given I have invalid plan tree data
        When I validate the plan tree
        Then the first error message should identify "node[0]" and the specific field issue
