UAT: SubplanService.spawn() does not pass parent plan's multi_project_metadata to child plans — spec requires child plans to inherit parent's project-scoped associations #4580

Open
opened 2026-04-08 15:49:42 +00:00 by HAL9000 · 0 comments
Owner

Bug Report

Feature Area: Multi-project and hierarchical plans — child plan multi-project metadata inheritance

What Was Tested

Code analysis of SubplanService.spawn() in src/cleveragents/application/services/subplan_service.py (lines 259–284) against the spec requirement for multi-project metadata inheritance in plan hierarchies.

Expected Behavior (from spec)

From docs/specification.md (line 22576):

Child plan inheritance: Child plans (spawned via subplan_spawn or subplan_parallel_spawn) inherit their parent plan's project-scoped and plan-scoped resource/validation associations by default.

From docs/specification.md (line 20035–20040):

In multi-project execution:

  • Strategize must clarify which steps affect which projects.
  • Execution must isolate sandboxes per project OR define a composite sandbox.
  • Apply must commit changes to each project separately.
  • Tool resource bindings are resolved per-project — the same tool may bind to different resources depending on which project context it runs in.

When a parent plan has multi_project_metadata (resolved project scopes, cross-project dependencies, resource isolation), child plans should inherit this metadata so they can correctly resolve per-project resource bindings and sandbox isolation.

Actual Behavior (bug)

SubplanService.spawn() creates child Plan domain objects but does not pass the parent plan's multi_project_metadata to the child plans:

# src/cleveragents/application/services/subplan_service.py, lines 259-284
child_plan: Plan = Plan(
    identity=PlanIdentity(
        plan_id=subplan_id,
        parent_plan_id=parent_id,
        root_plan_id=root_id,
    ),
    namespaced_name=NamespacedName(...),
    description=entry.description or f"Child plan for {entry.action_name}",
    definition_of_done=parent_plan.definition_of_done,
    action_name=entry.action_name,
    phase=PlanPhase.STRATEGIZE,
    processing_state=ProcessingState.QUEUED,
    strategy_actor=parent_plan.strategy_actor,
    execution_actor=parent_plan.execution_actor,
    project_links=list(parent_plan.project_links),  # ✓ Raw project links copied
    timestamps=PlanTimestamps(),
    created_by=parent_plan.created_by,
    reusable=parent_plan.reusable,
    read_only=parent_plan.read_only,
    # ❌ MISSING: multi_project_metadata=parent_plan.multi_project_metadata
)

While project_links (the raw project link list) is copied, the multi_project_metadata (which contains the resolved ProjectScope objects with resource IDs, changeset summaries, and cross-project dependency edges) is NOT passed to child plans.

Impact on Multi-Project Plans (Example 4)

In Example 4 (Multi-Project Dependency Update), the parent plan has:

  • project_links: [common-lib, user-service, order-service, billing-service]
  • multi_project_metadata.project_scopes: Each scope has resolved resource_ids for its project

When the parent spawns child plans (one per service), each child plan needs to know:

  1. Which resource IDs belong to its specific project (for sandbox isolation)
  2. Whether its project is read-only or writable
  3. Cross-project dependency edges (e.g., common-lib must be applied first)

Without multi_project_metadata, child plans cannot correctly:

  • Resolve per-project resource bindings during execution
  • Enforce sandbox isolation per project
  • Track per-project changeset summaries
  • Respect cross-project dependency ordering

Code Location

  • File: src/cleveragents/application/services/subplan_service.py
  • Lines: 259–284 (child plan creation in spawn())

Fix

Pass the parent's multi_project_metadata to child plans:

child_plan: Plan = Plan(
    identity=PlanIdentity(...),
    ...
    project_links=list(parent_plan.project_links),
    multi_project_metadata=parent_plan.multi_project_metadata,  # ✅ Inherit resolved scopes
)

Note: The child plan may need its own scoped view (only the projects it's responsible for), but at minimum it should inherit the parent's full metadata so it can resolve resource bindings correctly.


Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: uat-tester

## Bug Report **Feature Area:** Multi-project and hierarchical plans — child plan multi-project metadata inheritance ### What Was Tested Code analysis of `SubplanService.spawn()` in `src/cleveragents/application/services/subplan_service.py` (lines 259–284) against the spec requirement for multi-project metadata inheritance in plan hierarchies. ### Expected Behavior (from spec) From `docs/specification.md` (line 22576): > **Child plan inheritance**: Child plans (spawned via `subplan_spawn` or `subplan_parallel_spawn`) inherit their parent plan's project-scoped and plan-scoped resource/validation associations by default. From `docs/specification.md` (line 20035–20040): > In multi-project execution: > * Strategize must clarify which steps affect which projects. > * Execution must isolate sandboxes per project OR define a composite sandbox. > * Apply must commit changes to each project separately. > * Tool resource bindings are resolved per-project — the same tool may bind to different resources depending on which project context it runs in. When a parent plan has `multi_project_metadata` (resolved project scopes, cross-project dependencies, resource isolation), child plans should inherit this metadata so they can correctly resolve per-project resource bindings and sandbox isolation. ### Actual Behavior (bug) `SubplanService.spawn()` creates child `Plan` domain objects but does **not** pass the parent plan's `multi_project_metadata` to the child plans: ```python # src/cleveragents/application/services/subplan_service.py, lines 259-284 child_plan: Plan = Plan( identity=PlanIdentity( plan_id=subplan_id, parent_plan_id=parent_id, root_plan_id=root_id, ), namespaced_name=NamespacedName(...), description=entry.description or f"Child plan for {entry.action_name}", definition_of_done=parent_plan.definition_of_done, action_name=entry.action_name, phase=PlanPhase.STRATEGIZE, processing_state=ProcessingState.QUEUED, strategy_actor=parent_plan.strategy_actor, execution_actor=parent_plan.execution_actor, project_links=list(parent_plan.project_links), # ✓ Raw project links copied timestamps=PlanTimestamps(), created_by=parent_plan.created_by, reusable=parent_plan.reusable, read_only=parent_plan.read_only, # ❌ MISSING: multi_project_metadata=parent_plan.multi_project_metadata ) ``` While `project_links` (the raw project link list) is copied, the `multi_project_metadata` (which contains the **resolved** `ProjectScope` objects with resource IDs, changeset summaries, and cross-project dependency edges) is NOT passed to child plans. ### Impact on Multi-Project Plans (Example 4) In Example 4 (Multi-Project Dependency Update), the parent plan has: - `project_links`: `[common-lib, user-service, order-service, billing-service]` - `multi_project_metadata.project_scopes`: Each scope has resolved `resource_ids` for its project When the parent spawns child plans (one per service), each child plan needs to know: 1. Which resource IDs belong to its specific project (for sandbox isolation) 2. Whether its project is read-only or writable 3. Cross-project dependency edges (e.g., `common-lib` must be applied first) Without `multi_project_metadata`, child plans cannot correctly: - Resolve per-project resource bindings during execution - Enforce sandbox isolation per project - Track per-project changeset summaries - Respect cross-project dependency ordering ### Code Location - **File**: `src/cleveragents/application/services/subplan_service.py` - **Lines**: 259–284 (child plan creation in `spawn()`) ### Fix Pass the parent's `multi_project_metadata` to child plans: ```python child_plan: Plan = Plan( identity=PlanIdentity(...), ... project_links=list(parent_plan.project_links), multi_project_metadata=parent_plan.multi_project_metadata, # ✅ Inherit resolved scopes ) ``` Note: The child plan may need its own scoped view (only the projects it's responsible for), but at minimum it should inherit the parent's full metadata so it can resolve resource bindings correctly. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.7.0 milestone 2026-04-08 17:40:51 +00:00
HAL9000 modified the milestone from v3.7.0 to v3.5.0 2026-04-08 17:41:25 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#4580
No description provided.