Files
temp/features/plan_subplan_tool.feature
T
aditya b888afab71 feat(actor): add plan_subplan tool and decision emission
Add builtin/plan-subplan tool for strategy actors to emit SUBPLAN_SPAWN
or SUBPLAN_PARALLEL_SPAWN decisions when decomposing a plan into child
plans. Implements all acceptance criteria from issue #198:

- SubplanPayload (Pydantic) validates goal, resource_scopes/project_ref
  (at least one required), merge_strategy, max_parallel (1-50), parallel
  flag, dependencies, and context_view override.
- Defaults: merge_strategy=git_three_way, max_parallel=5, parallel=False,
  dependencies=[]. Omitted fields inherit sensible values automatically.
- make_plan_subplan_spec(decision_service=None) factory supports optional
  DecisionService injection for persistent decision recording.
- _build_rationale() generates human-readable rationale text (goal, scope,
  execution mode, dependencies, context_view) surfaced in plan explain.
- register_subplan_tool() added to tool/builtins/__init__.py for bulk
  registration. PLAN_SUBPLAN_SPEC exported as the default ready-to-use spec.
- Actor YAML example (examples/actors/strategy_with_subplan.yaml) with
  annotated serial and parallel spawn payload examples.
- Behave BDD: 20 scenarios, 70 steps covering validation, defaults,
  decision type, rationale, service injection, registry, and ToolRunner.
- Robot Framework: 9 smoke tests via robot/plan_subplan_tool.robot.
- ASV benchmarks: benchmarks/subplan_actor_tool_bench.py (5 suites).
- Coverage: 100% on subplan_tool.py. Lint, typecheck, and security clean.

ISSUES CLOSED: #198
2026-02-27 08:02:48 +00:00

140 lines
6.6 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"
# ---------------------------------------------------------------------------
# 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