9c49bbc4db
Convert alternatives_considered list of strings to structured objects with index (1-based), description, and chosen fields in _build_explain_dict(). Rename output field from alternatives_considered to alternatives. Update BDD tests in plan_explain.feature, plan_explain_cli_coverage.feature, and plan_explain_steps.py to validate the new structured format. Closes #9166
232 lines
10 KiB
Gherkin
232 lines
10 KiB
Gherkin
Feature: Plan explain and tree CLI command coverage
|
|
Exercises the CLI-level code paths in plan explain, plan tree,
|
|
plan correct, plan resume, plan revert, and the read-only guards
|
|
in plan execute / plan apply that are not covered by the existing
|
|
unit-level plan_explain.feature.
|
|
|
|
# ------------------------------------------------------------------
|
|
# explain_decision_cmd - CLI invocation with rich format
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Explain CLI renders rich table for a known decision
|
|
Given pec a mock DecisionService returning a valid decision
|
|
When pec I invoke "explain" with the decision id
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Decision Details"
|
|
And pec the output should contain "decision_id"
|
|
|
|
Scenario: Explain CLI renders json format
|
|
Given pec a mock DecisionService returning a valid decision
|
|
When pec I invoke "explain" with format "json"
|
|
Then pec the exit code should be 0
|
|
And pec the output should be valid json
|
|
|
|
Scenario: Explain CLI renders yaml format
|
|
Given pec a mock DecisionService returning a valid decision
|
|
When pec I invoke "explain" with format "yaml"
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "decision_id:"
|
|
|
|
Scenario: Explain CLI returns error for unknown decision
|
|
Given pec a mock DecisionService returning None for get_decision
|
|
When pec I invoke "explain" with the decision id
|
|
Then pec the exit code should be 1
|
|
And pec the output should contain "not found"
|
|
|
|
Scenario: Explain CLI with show-context flag
|
|
Given pec a mock DecisionService returning a decision with context snapshot
|
|
When pec I invoke "explain" with flags "--show-context"
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "context_snapshot"
|
|
|
|
Scenario: Explain CLI with show-reasoning flag
|
|
Given pec a mock DecisionService returning a decision with reasoning
|
|
When pec I invoke "explain" with flags "--show-reasoning"
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "rationale"
|
|
|
|
Scenario: Explain CLI includes alternatives by default
|
|
Given pec a mock DecisionService returning a decision with alternatives
|
|
When pec I invoke "explain" with the decision id
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "alternatives"
|
|
|
|
# ------------------------------------------------------------------
|
|
# tree_decisions_cmd - rich tree format
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Tree CLI renders rich tree for a plan with decisions
|
|
Given pec a mock DecisionService returning a list of decisions
|
|
When pec I invoke "tree" with a plan id
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Plan"
|
|
|
|
Scenario: Tree CLI renders json format
|
|
Given pec a mock DecisionService returning a list of decisions
|
|
When pec I invoke "tree" with format "json"
|
|
Then pec the exit code should be 0
|
|
And pec the output should be valid json envelope
|
|
|
|
Scenario: Tree CLI renders yaml format
|
|
Given pec a mock DecisionService returning a list of decisions
|
|
When pec I invoke "tree" with format "yaml"
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "command:"
|
|
|
|
Scenario: Tree CLI renders table format
|
|
Given pec a mock DecisionService returning a list of decisions
|
|
When pec I invoke "tree" with format "table"
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Decision Tree"
|
|
|
|
Scenario: Tree CLI table format with depth limit
|
|
Given pec a mock DecisionService returning a deep decision list
|
|
When pec I invoke "tree" with format "table" and depth 1
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Decision Tree"
|
|
|
|
Scenario: Tree CLI rich format with depth limit
|
|
Given pec a mock DecisionService returning a deep decision list
|
|
When pec I invoke "tree" with depth 1
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Plan"
|
|
|
|
Scenario: Tree CLI with show-superseded flag
|
|
Given pec a mock DecisionService returning decisions with superseded
|
|
When pec I invoke "tree" with flags "--show-superseded"
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Which framework?"
|
|
|
|
Scenario: Tree CLI for plan with no decisions
|
|
Given pec a mock DecisionService returning an empty list
|
|
When pec I invoke "tree" with a plan id
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "No decisions found"
|
|
|
|
# ------------------------------------------------------------------
|
|
# build_decision_tree edge case: child_id not in by_id
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Tree builder skips orphan child references gracefully
|
|
Given pec a decision list where a child references a missing parent
|
|
When pec I build the tree from orphan decisions
|
|
Then pec the tree should exclude the superseded grandchild
|
|
|
|
# ------------------------------------------------------------------
|
|
# _resolve_active_plan_id
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Resolve active plan id returns first non-terminal plan
|
|
Given pec a lifecycle service with one active plan
|
|
When pec I call resolve active plan id
|
|
Then pec the resolved plan id should match the active plan
|
|
|
|
# ------------------------------------------------------------------
|
|
# revert_plan error handlers
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Revert plan with InvalidPhaseTransitionError
|
|
Given pec a lifecycle service that raises InvalidPhaseTransitionError on revert
|
|
When pec I invoke "revert" with plan id and target "strategize"
|
|
Then pec the exit code should be nonzero
|
|
And pec the output should contain "Invalid reversion"
|
|
|
|
Scenario: Revert plan with PlanError
|
|
Given pec a lifecycle service that raises PlanError on revert
|
|
When pec I invoke "revert" with plan id and target "strategize"
|
|
Then pec the exit code should be nonzero
|
|
And pec the output should contain "Cannot revert"
|
|
|
|
# ------------------------------------------------------------------
|
|
# correct_decision - rich format dry-run
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Correct decision dry-run with rich format shows impact panel
|
|
Given pec a mock CorrectionService with dry-run impact
|
|
When pec I invoke "correct" in dry-run mode with rich format
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Correction Impact"
|
|
|
|
Scenario: Correct decision execute with yes flag shows success
|
|
Given pec a mock CorrectionService with execute result
|
|
When pec I invoke "correct" with yes flag
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Correction applied"
|
|
|
|
Scenario: Correct decision execute with reverted and new decisions
|
|
Given pec a mock CorrectionService with reverted and new decisions
|
|
When pec I invoke "correct" with yes flag
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Reverted"
|
|
And pec the output should contain "New decisions"
|
|
|
|
Scenario: Correct decision with confirmation prompt cancelled
|
|
Given pec a mock CorrectionService with execute result
|
|
When pec I invoke "correct" without yes and decline
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Cancelled"
|
|
|
|
Scenario: Correct decision with ResourceNotFoundError
|
|
Given pec a mock CorrectionService that raises ResourceNotFoundError
|
|
When pec I invoke "correct" with yes flag
|
|
Then pec the exit code should be nonzero
|
|
And pec the output should contain "Not found"
|
|
And pec the output should not contain "Validation Error"
|
|
|
|
Scenario: Correct decision with ValidationError
|
|
Given pec a mock CorrectionService that raises ValidationError
|
|
When pec I invoke "correct" with yes flag
|
|
Then pec the exit code should be nonzero
|
|
And pec the output should contain "Validation Error"
|
|
And pec the output should not contain "Not found"
|
|
|
|
Scenario: Correct decision with CleverAgentsError
|
|
Given pec a mock CorrectionService that raises CleverAgentsError
|
|
When pec I invoke "correct" with yes flag
|
|
Then pec the exit code should be nonzero
|
|
And pec the output should contain "Error"
|
|
|
|
# ------------------------------------------------------------------
|
|
# resume_plan_cmd
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Resume plan with rich format shows panel
|
|
Given pec a mock PlanResumeService returning a summary
|
|
When pec I invoke "resume" with a plan id
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "Resume Summary"
|
|
|
|
Scenario: Resume plan with dry-run shows dry-run label
|
|
Given pec a mock PlanResumeService returning a summary
|
|
When pec I invoke "resume" with dry-run flag
|
|
Then pec the exit code should be 0
|
|
And pec the output should contain "dry-run"
|
|
|
|
Scenario: Resume plan with json format
|
|
Given pec a mock PlanResumeService returning a summary
|
|
When pec I invoke "resume" with format "json"
|
|
Then pec the exit code should be 0
|
|
And pec the output should be valid json
|
|
|
|
Scenario: Resume plan with PlanError
|
|
Given pec a mock PlanResumeService that raises PlanError
|
|
When pec I invoke "resume" with a plan id
|
|
Then pec the exit code should be nonzero
|
|
And pec the output should contain "Cannot resume"
|
|
|
|
# ------------------------------------------------------------------
|
|
# Read-only plan guards in execute and apply
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Execute plan aborts for read-only plan
|
|
Given pec a lifecycle service returning a read-only plan
|
|
When pec I invoke "execute" with the read-only plan id
|
|
Then pec the exit code should be nonzero
|
|
And pec the output should contain "read-only"
|
|
|
|
Scenario: Apply plan aborts for read-only plan
|
|
Given pec a lifecycle service returning a read-only plan
|
|
When pec I invoke "apply" with the read-only plan id
|
|
Then pec the exit code should be nonzero
|
|
And pec the output should contain "read-only"
|