Feature: M3 decision tree, validation gating, and invariant enforcement smoke tests
  As a developer working with the CleverAgents M3 milestone
  I want to verify decision trees, corrections, validation lifecycle,
  and invariant constraints work end-to-end via the CLI
  So that the M3 foundation for decision + validation + invariant is solid

  Background:
    Given a m3 smoke test runner
    And a m3 smoke mocked environment

  # --- Decision tree fixture loading ---

  Scenario: M3 smoke load decision tree fixture
    When I m3 smoke load the decision tree fixture
    Then the m3 smoke decision tree fixture should have a minimal tree entry
    And the m3 smoke minimal tree should contain 2 decisions

  Scenario: M3 smoke load decision tree with invariant node
    When I m3 smoke load the decision tree fixture
    Then the m3 smoke decision tree fixture should have an invariant tree entry
    And the m3 smoke invariant tree should contain an invariant_enforced decision

  Scenario: M3 smoke load decision tree with correction
    When I m3 smoke load the decision tree fixture
    Then the m3 smoke decision tree fixture should have a correction tree entry
    And the m3 smoke correction tree should contain a superseded decision
    And the m3 smoke correction tree should contain a correction decision

  # --- Validation fixture loading ---

  Scenario: M3 smoke load validation attachment fixtures
    When I m3 smoke load the validation attachment fixture
    Then the m3 smoke validation fixture should have a coverage entry
    And the m3 smoke coverage validation should have mode "required"

  Scenario: M3 smoke load validation attachment with informational mode
    When I m3 smoke load the validation attachment fixture
    Then the m3 smoke validation fixture should have a lint entry
    And the m3 smoke lint validation should have mode "informational"

  # --- Invariant fixture loading ---

  Scenario: M3 smoke load invariant config fixtures
    When I m3 smoke load the invariant config fixture
    Then the m3 smoke invariant fixture should have a global entry
    And the m3 smoke global invariant text should be "Never delete production data"

  Scenario: M3 smoke load invariant merge set
    When I m3 smoke load the invariant config fixture
    Then the m3 smoke invariant fixture should have a merge set entry
    And the m3 smoke merge set should define expected merged count 4

  # --- Invariant CLI: add ---

  Scenario: M3 smoke invariant add global
    When I m3 smoke invoke invariant add with text "Never delete production data" and global scope
    Then the m3 smoke invariant add should succeed
    And the m3 smoke invariant output should contain "Never delete production data"

  Scenario: M3 smoke invariant add project scoped
    When I m3 smoke invoke invariant add with text "All API changes need tests" and project "local/m3-smoke-proj"
    Then the m3 smoke invariant add should succeed

  # --- Invariant CLI: list ---

  Scenario: M3 smoke invariant list shows entries
    Given m3 smoke invariants have been added
    When I m3 smoke invoke invariant list
    Then the m3 smoke invariant list should succeed
    And the m3 smoke invariant list output should contain "Never delete production data"

  Scenario: M3 smoke invariant list with project filter
    Given m3 smoke invariants have been added
    When I m3 smoke invoke invariant list with project filter "local/m3-smoke-proj"
    Then the m3 smoke invariant list should succeed

  # --- Invariant CLI: remove ---

  Scenario: M3 smoke invariant remove by id
    Given m3 smoke invariants have been added
    When I m3 smoke invoke invariant remove with a known id
    Then the m3 smoke invariant remove should succeed

  Scenario: M3 smoke invariant remove unknown id fails
    When I m3 smoke invoke invariant remove with id "01UNKNOWN000000000000000000"
    Then the m3 smoke invariant remove should fail

  # --- Validation CLI: add ---

  Scenario: M3 smoke validation add from config
    Given a m3 smoke temporary validation config file
    When I m3 smoke invoke validation add with the config
    Then the m3 smoke validation add should succeed
    And the m3 smoke validation output should contain "coverage-check"

  # --- Validation CLI: attach ---

  Scenario: M3 smoke validation attach to resource
    Given a m3 smoke validation "local/coverage-check" is registered
    When I m3 smoke invoke validation attach "local/coverage-check" to "git-checkout/my-repo"
    Then the m3 smoke validation attach should succeed

  # --- Validation CLI: detach ---

  Scenario: M3 smoke validation detach by id
    Given a m3 smoke validation attachment exists
    When I m3 smoke invoke validation detach with the attachment id
    Then the m3 smoke validation detach should succeed

  # --- Plan correct CLI ---

  Scenario: M3 smoke plan correct dry run
    Given a m3 smoke plan with decisions exists
    When I m3 smoke invoke plan correct in dry-run mode
    Then the m3 smoke plan correct dry run should succeed
    And the m3 smoke correction output should contain "risk_level"

  Scenario: M3 smoke plan correct revert executes
    Given a m3 smoke plan with decisions exists
    When I m3 smoke invoke plan correct in revert mode
    Then the m3 smoke plan correct should succeed

  Scenario: M3 smoke plan correct append executes
    Given a m3 smoke plan with decisions exists
    When I m3 smoke invoke plan correct in append mode
    Then the m3 smoke plan correct should succeed

  # --- Negative cases ---

  Scenario: M3 smoke plan correct with empty guidance fails
    When I m3 smoke invoke plan correct with empty guidance
    Then the m3 smoke plan correct should fail

  Scenario: M3 smoke plan correct with invalid mode fails
    When I m3 smoke invoke plan correct with invalid mode "rollback"
    Then the m3 smoke plan correct should fail
