UAT: Plan.effective_profile_snapshot is never populated by PlanLifecycleService.use_action() — spec requires frozen automation profile snapshot for audit/reproducibility #4029

Open
opened 2026-04-06 08:46:22 +00:00 by freemo · 0 comments
Owner

Metadata

  • Branch: fix/plan-lifecycle-effective-profile-snapshot
  • Commit Message: fix(plan): populate effective_profile_snapshot in PlanLifecycleService.use_action()
  • Milestone: None (backlog)
  • Parent Epic: #3370

What Was Tested

Code-level analysis of src/cleveragents/domain/models/core/plan.py and src/cleveragents/application/services/plan_lifecycle_service.py.

Expected Behavior (from spec)

The spec requires that a frozen JSON snapshot of the automation profile be captured at plan creation time for audit and reproducibility purposes. The effective_profile_snapshot field on Plan is intended to store this snapshot.

Actual Behavior

The Plan model has an effective_profile_snapshot field with a default value of "{}" (empty JSON object):

# From src/cleveragents/domain/models/core/plan.py
effective_profile_snapshot: str = Field(
    default="{}",
    description=(
        "Frozen JSON snapshot of the automation profile at plan creation time"
    ),
)

The code comment in plan.py explicitly acknowledges this is a problem:

"NOTE: The default '{}' exists for backward compatibility with code paths that create Plan objects before the snapshot is populated. New plans SHOULD explicitly set this field to the resolved profile JSON at creation time; the empty default does not satisfy the spec intent of capturing a frozen profile for audit purposes."

However, PlanLifecycleService.use_action() in src/cleveragents/application/services/plan_lifecycle_service.py creates the Plan object without setting effective_profile_snapshot:

plan = Plan(
    identity=PlanIdentity(plan_id=plan_id),
    namespaced_name=...,
    action_name=action_full_name,
    description=...,
    phase=PlanPhase.STRATEGIZE,
    processing_state=ProcessingState.QUEUED,
    automation_profile=resolved_profile,  # Profile IS resolved...
    # ... but effective_profile_snapshot is never set!
    # It defaults to "{}" instead of capturing the resolved profile
)

The resolved_profile (an AutomationProfileRef with profile_name and provenance) is correctly resolved but never serialized into effective_profile_snapshot.

Impact

  • All plans created via agents plan use have effective_profile_snapshot = "{}"
  • The audit trail for automation profile decisions is incomplete
  • Reproducibility of plan execution is compromised since the profile snapshot is empty
  • This violates the spec's audit/reproducibility requirement

Code Locations

  • src/cleveragents/domain/models/core/plan.py, effective_profile_snapshot field (line ~820)
  • src/cleveragents/application/services/plan_lifecycle_service.py, use_action() method

Fix Required

In PlanLifecycleService.use_action(), after resolving resolved_profile, serialize it to JSON and set effective_profile_snapshot:

import json

# After resolving the profile:
resolved_profile = self._resolve_plan_profile_ref(...)

# Serialize the profile snapshot for audit
profile_snapshot = json.dumps({
    "profile_name": resolved_profile.profile_name,
    "provenance": resolved_profile.provenance.value,
})

plan = Plan(
    ...
    automation_profile=resolved_profile,
    effective_profile_snapshot=profile_snapshot,  # Add this
)

Subtasks

  • Serialize resolved_profile to JSON in PlanLifecycleService.use_action() and assign to effective_profile_snapshot
  • Write Behave scenario: Plan.effective_profile_snapshot is populated with the resolved profile JSON when use_action() is called
  • Write Behave scenario: effective_profile_snapshot contains correct profile_name and provenance values
  • Verify no other Plan construction sites omit effective_profile_snapshot (audit all call sites)
  • Update any related integration tests in robot/ if applicable

Definition of Done

  • PlanLifecycleService.use_action() sets effective_profile_snapshot to a non-empty JSON string containing the resolved profile name and provenance
  • All plans created via agents plan use have a populated effective_profile_snapshot
  • Behave scenarios cover the fix and pass
  • No other Plan construction sites leave effective_profile_snapshot as "{}"
  • All nox stages pass
  • Coverage >= 97%

Backlog note: This issue was discovered during autonomous operation
on milestone v3.5.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.


Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/plan-lifecycle-effective-profile-snapshot` - **Commit Message**: `fix(plan): populate effective_profile_snapshot in PlanLifecycleService.use_action()` - **Milestone**: None (backlog) - **Parent Epic**: #3370 ## What Was Tested Code-level analysis of `src/cleveragents/domain/models/core/plan.py` and `src/cleveragents/application/services/plan_lifecycle_service.py`. ## Expected Behavior (from spec) The spec requires that a frozen JSON snapshot of the automation profile be captured at plan creation time for audit and reproducibility purposes. The `effective_profile_snapshot` field on `Plan` is intended to store this snapshot. ## Actual Behavior The `Plan` model has an `effective_profile_snapshot` field with a default value of `"{}"` (empty JSON object): ```python # From src/cleveragents/domain/models/core/plan.py effective_profile_snapshot: str = Field( default="{}", description=( "Frozen JSON snapshot of the automation profile at plan creation time" ), ) ``` The code comment in `plan.py` explicitly acknowledges this is a problem: > "NOTE: The default '{}' exists for backward compatibility with code paths that create Plan objects before the snapshot is populated. New plans SHOULD explicitly set this field to the resolved profile JSON at creation time; the empty default does not satisfy the spec intent of capturing a frozen profile for audit purposes." However, `PlanLifecycleService.use_action()` in `src/cleveragents/application/services/plan_lifecycle_service.py` creates the `Plan` object without setting `effective_profile_snapshot`: ```python plan = Plan( identity=PlanIdentity(plan_id=plan_id), namespaced_name=..., action_name=action_full_name, description=..., phase=PlanPhase.STRATEGIZE, processing_state=ProcessingState.QUEUED, automation_profile=resolved_profile, # Profile IS resolved... # ... but effective_profile_snapshot is never set! # It defaults to "{}" instead of capturing the resolved profile ) ``` The `resolved_profile` (an `AutomationProfileRef` with `profile_name` and `provenance`) is correctly resolved but never serialized into `effective_profile_snapshot`. ## Impact - All plans created via `agents plan use` have `effective_profile_snapshot = "{}"` - The audit trail for automation profile decisions is incomplete - Reproducibility of plan execution is compromised since the profile snapshot is empty - This violates the spec's audit/reproducibility requirement ## Code Locations - `src/cleveragents/domain/models/core/plan.py`, `effective_profile_snapshot` field (line ~820) - `src/cleveragents/application/services/plan_lifecycle_service.py`, `use_action()` method ## Fix Required In `PlanLifecycleService.use_action()`, after resolving `resolved_profile`, serialize it to JSON and set `effective_profile_snapshot`: ```python import json # After resolving the profile: resolved_profile = self._resolve_plan_profile_ref(...) # Serialize the profile snapshot for audit profile_snapshot = json.dumps({ "profile_name": resolved_profile.profile_name, "provenance": resolved_profile.provenance.value, }) plan = Plan( ... automation_profile=resolved_profile, effective_profile_snapshot=profile_snapshot, # Add this ) ``` ## Subtasks - [ ] Serialize `resolved_profile` to JSON in `PlanLifecycleService.use_action()` and assign to `effective_profile_snapshot` - [ ] Write Behave scenario: `Plan.effective_profile_snapshot` is populated with the resolved profile JSON when `use_action()` is called - [ ] Write Behave scenario: `effective_profile_snapshot` contains correct `profile_name` and `provenance` values - [ ] Verify no other `Plan` construction sites omit `effective_profile_snapshot` (audit all call sites) - [ ] Update any related integration tests in `robot/` if applicable ## Definition of Done - [ ] `PlanLifecycleService.use_action()` sets `effective_profile_snapshot` to a non-empty JSON string containing the resolved profile name and provenance - [ ] All plans created via `agents plan use` have a populated `effective_profile_snapshot` - [ ] Behave scenarios cover the fix and pass - [ ] No other `Plan` construction sites leave `effective_profile_snapshot` as `"{}"` - [ ] All nox stages pass - [ ] Coverage >= 97% > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.5.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
HAL9000 added this to the v3.5.0 milestone 2026-04-09 03:11:47 +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.

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