Files
cleveragents-core/features/plan_subplan_tool.feature
aditya ef65996ca2 fix(actor): address code review findings on plan_subplan tool
- Return parent_decision_id in handler result dict and add meaningful
  assertion to the corresponding Behave scenario (B1)
- Add ULID format validators to SubplanPayload for plan_id, dependencies,
  and parent_decision_id, consistent with Decision model validation (S1)
- Add non-empty string validator for resource_scopes items (S2)
- Narrow broad except Exception to except (ValidationError, ValueError)
  so programming errors surface as real failures (S3)
- Document strategy_with_subplan.yaml in actors_examples.md and assert
  it is referenced in the "Verify all examples are documented" scenario (B2)

ISSUES CLOSED: #198
2026-03-02 08:17:21 +00:00

165 lines
7.8 KiB
Gherkin

Feature: plan_subplan builtin tool — decision emission
As a strategy actor
I want to call the builtin/plan-subplan tool
So that SUBPLAN_SPAWN or SUBPLAN_PARALLEL_SPAWN decisions are emitted
with validated payloads, correct defaults, and rich rationale text
# ---------------------------------------------------------------------------
# Payload validation
# ---------------------------------------------------------------------------
Scenario: Serial subplan with resource_scopes succeeds
Given a plan_subplan tool handler
When I invoke plan_subplan with goal "Refactor auth module" and resource_scopes ["src/auth"]
Then the plan_subplan result should succeed
And the plan_subplan result decision_type should be "subplan_spawn"
Scenario: Serial subplan with project_ref succeeds
Given a plan_subplan tool handler
When I invoke plan_subplan with goal "Migrate database" and project_ref "projects/db"
Then the plan_subplan result should succeed
And the plan_subplan result decision_type should be "subplan_spawn"
Scenario: Parallel subplan with dependencies succeeds
Given a plan_subplan tool handler
When I invoke parallel plan_subplan with dependencies ["01ARZ3NDEKTSV4RRFFQ69G5FAV"]
Then the plan_subplan result should succeed
And the plan_subplan result decision_type should be "subplan_parallel_spawn"
Scenario: Missing resource_scopes and project_ref raises error
Given a plan_subplan tool handler
When I invoke plan_subplan with goal "Bad call" and no resource scope or project ref
Then the plan_subplan result should fail
And the plan_subplan error should mention "resource_scopes"
Scenario: Empty goal raises error
Given a plan_subplan tool handler
When I invoke plan_subplan with empty goal and resource_scopes ["src/"]
Then the plan_subplan result should fail
And the plan_subplan error should mention "goal"
Scenario: max_parallel below minimum raises error
Given a plan_subplan tool handler
When I invoke parallel plan_subplan with max_parallel 0
Then the plan_subplan result should fail
And the plan_subplan error should mention "max_parallel"
Scenario: max_parallel above maximum raises error
Given a plan_subplan tool handler
When I invoke parallel plan_subplan with max_parallel 51
Then the plan_subplan result should fail
And the plan_subplan error should mention "max_parallel"
Scenario: Invalid merge_strategy raises error
Given a plan_subplan tool handler
When I invoke plan_subplan with invalid merge_strategy "merge_magic"
Then the plan_subplan result should fail
And the plan_subplan error should mention "merge_strategy"
Scenario: Invalid context_view raises error
Given a plan_subplan tool handler
When I invoke plan_subplan with invalid context_view "omniscient"
Then the plan_subplan result should fail
And the plan_subplan error should mention "context_view"
# ---------------------------------------------------------------------------
# Default values
# ---------------------------------------------------------------------------
Scenario: merge_strategy defaults to git_three_way
Given a plan_subplan tool handler
When I invoke plan_subplan with goal "Deploy frontend" and resource_scopes ["src/ui"]
Then the plan_subplan result output merge_strategy should be "git_three_way"
Scenario: max_parallel defaults to 5
Given a plan_subplan tool handler
When I invoke parallel plan_subplan with no max_parallel override
Then the plan_subplan result output max_parallel should be 5
Scenario: parallel defaults to False for serial spawn
Given a plan_subplan tool handler
When I invoke plan_subplan with goal "Clean logs" and resource_scopes ["logs/"]
Then the plan_subplan result output parallel should be false
Scenario: dependencies defaults to empty list
Given a plan_subplan tool handler
When I invoke plan_subplan with goal "Build docs" and resource_scopes ["docs/"]
Then the plan_subplan result output dependencies should be empty
# ---------------------------------------------------------------------------
# Rationale text
# ---------------------------------------------------------------------------
Scenario: Rationale is auto-generated for serial subplan
Given a plan_subplan tool handler
When I invoke plan_subplan with goal "Refactor models" and resource_scopes ["src/models"]
Then the plan_subplan result rationale should mention the goal
Scenario: Rationale for parallel subplan mentions parallel execution
Given a plan_subplan tool handler
When I invoke parallel plan_subplan with dependencies []
Then the plan_subplan result rationale should mention "parallel"
# ---------------------------------------------------------------------------
# Context view override
# ---------------------------------------------------------------------------
Scenario: Context view override is stored in output
Given a plan_subplan tool handler
When I invoke plan_subplan with context_view "executor" and resource_scopes ["src/"]
Then the plan_subplan result output context_view should be "executor"
Scenario: parent_decision_id is included in the decision when provided
Given a plan_subplan tool handler
When I invoke plan_subplan with a parent_decision_id and resource_scopes ["src/"]
Then the plan_subplan result should succeed
And the plan_subplan result decision_type should be "subplan_spawn"
And the plan_subplan result output parent_decision_id should be "01ARZ3NDEKTSV4RRFFQ69G5FAV"
Scenario: Invalid ULID for plan_id raises error
Given a plan_subplan tool handler
When I invoke plan_subplan with invalid plan_id "not-a-ulid" and resource_scopes ["src/"]
Then the plan_subplan result should fail
And the plan_subplan error should mention "plan_id"
Scenario: Invalid ULID in dependencies raises error
Given a plan_subplan tool handler
When I invoke plan_subplan with invalid dependency "bad-dep" and resource_scopes ["src/"]
Then the plan_subplan result should fail
And the plan_subplan error should mention "dependencies"
Scenario: Invalid ULID for parent_decision_id raises error
Given a plan_subplan tool handler
When I invoke plan_subplan with invalid parent_decision_id "not-a-ulid" and resource_scopes ["src/"]
Then the plan_subplan result should fail
And the plan_subplan error should mention "parent_decision_id"
Scenario: Empty string in resource_scopes raises error
Given a plan_subplan tool handler
When I invoke plan_subplan with empty resource scope item
Then the plan_subplan result should fail
And the plan_subplan error should mention "resource_scopes"
# ---------------------------------------------------------------------------
# Decision service integration
# ---------------------------------------------------------------------------
Scenario: Tool records decision via injected decision service
Given a plan_subplan tool handler with a stub decision service
When I invoke plan_subplan with goal "Run tests" and resource_scopes ["tests/"]
Then the stub decision service should have recorded 1 decision
And the recorded decision type should be "subplan_spawn"
# ---------------------------------------------------------------------------
# Registration and execution via ToolRunner
# ---------------------------------------------------------------------------
Scenario: Tool registers successfully into ToolRegistry
When I register the plan_subplan tool in a ToolRegistry
Then the registry should contain "builtin/plan-subplan"
Scenario: Tool executes via ToolRunner and returns success
Given a ToolRunner with the plan_subplan tool registered
When I run plan_subplan via the ToolRunner with valid inputs
Then the ToolRunner result should succeed