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