UAT: agents resource remove does not check project links before deletion — spec requires failure when resource is linked to a project #3406

Open
opened 2026-04-05 16:31:08 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/resource-remove-project-link-check
  • Commit Message: fix(cli): guard resource remove against linked projects per spec
  • Milestone: v3.6.0
  • Parent Epic: #398

Bug Description

The spec (docs/specification.md line 10953) explicitly states:

"This operation fails if the resource is linked to any project — use agents project unlink-resource first."

However, the current implementation of agents resource remove in /app/src/cleveragents/cli/commands/resource.py (the resource_remove function) only checks for DAG edges (parent/child resource relationships via ResourceEdgeModel), but does NOT check if the resource is linked to any project via ProjectResourceLinkModel.

Evidence:
The resource_remove function (lines ~1270-1330 in resource.py) does:

# Check for edges (DAG parent/child relationships)
edge_count: int = (
    session.query(ResourceEdgeModel)
    .filter(
        (ResourceEdgeModel.parent_id == res.resource_id)
        | (ResourceEdgeModel.child_id == res.resource_id)
    )
    .count()
)
if edge_count > 0:
    console.print(f"[red]Cannot remove resource...: {edge_count} edge(s) still reference it.[/red]")
    raise typer.Abort()

But there is no corresponding check against ProjectResourceLinkModel to see if the resource is linked to any project. A resource linked to a project can be silently deleted, leaving dangling project-resource links.

Steps to Reproduce

  1. Create a project: agents project create local/my-project
  2. Add a resource: agents resource add git-checkout local/my-repo --path /tmp/repo
  3. Link resource to project: agents project link-resource local/my-project local/my-repo
  4. Try to remove the resource: agents resource remove --yes local/my-repo
  5. Bug: The resource is deleted even though it is linked to a project. The spec requires this to fail with an error message telling the user to unlink first.

Expected Behavior (from spec)

$ agents resource remove local/my-repo
Error: Resource 'local/my-repo' is linked to 1 project(s).
Use 'agents project unlink-resource' first.

Fix Required

In the resource_remove function in /app/src/cleveragents/cli/commands/resource.py, add a check before deletion:

from cleveragents.infrastructure.database.models import ProjectResourceLinkModel

# Check for project links
project_link_count = (
    session.query(ProjectResourceLinkModel)
    .filter_by(resource_id=res.resource_id)
    .count()
)
if project_link_count > 0:
    console.print(
        f"[red]Cannot remove resource '{res.name or res.resource_id}': "
        f"linked to {project_link_count} project(s). "
        f"Use 'agents project unlink-resource' first.[/red]"
    )
    raise typer.Abort()

Code Location:

  • /app/src/cleveragents/cli/commands/resource.pyresource_remove function

This is a critical data integrity bug — resources linked to projects can be silently deleted, leaving orphaned project-resource links in the database.

Subtasks

  • Add ProjectResourceLinkModel project-link count check in resource_remove before the deletion block
  • Add Behave unit test scenario: resource remove fails when resource is linked to a project
  • Add Behave unit test scenario: resource remove succeeds when resource has no project links
  • Add Robot Framework integration test: end-to-end verification of the guard (create project, link resource, attempt remove, expect failure)
  • Verify error message matches spec wording and suggests agents project unlink-resource
  • Update any relevant docstrings or inline comments referencing the spec line

Definition of Done

  • resource_remove raises an error (does not delete) when the resource is linked to ≥1 project
  • Error message clearly names the resource, the number of linked projects, and the remediation command
  • All nox stages pass
  • Coverage >= 97%
  • Behave scenarios cover both the blocked and the allowed deletion paths
  • Robot Framework integration test confirms end-to-end behaviour

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

## Metadata - **Branch**: `fix/resource-remove-project-link-check` - **Commit Message**: `fix(cli): guard resource remove against linked projects per spec` - **Milestone**: v3.6.0 - **Parent Epic**: #398 ## Bug Description The spec (`docs/specification.md` line 10953) explicitly states: > "This operation fails if the resource is linked to any project — use `agents project unlink-resource` first." However, the current implementation of `agents resource remove` in `/app/src/cleveragents/cli/commands/resource.py` (the `resource_remove` function) only checks for DAG edges (parent/child resource relationships via `ResourceEdgeModel`), but does **NOT** check if the resource is linked to any project via `ProjectResourceLinkModel`. **Evidence:** The `resource_remove` function (lines ~1270-1330 in `resource.py`) does: ```python # Check for edges (DAG parent/child relationships) edge_count: int = ( session.query(ResourceEdgeModel) .filter( (ResourceEdgeModel.parent_id == res.resource_id) | (ResourceEdgeModel.child_id == res.resource_id) ) .count() ) if edge_count > 0: console.print(f"[red]Cannot remove resource...: {edge_count} edge(s) still reference it.[/red]") raise typer.Abort() ``` But there is **no** corresponding check against `ProjectResourceLinkModel` to see if the resource is linked to any project. A resource linked to a project can be silently deleted, leaving dangling project-resource links. ## Steps to Reproduce 1. Create a project: `agents project create local/my-project` 2. Add a resource: `agents resource add git-checkout local/my-repo --path /tmp/repo` 3. Link resource to project: `agents project link-resource local/my-project local/my-repo` 4. Try to remove the resource: `agents resource remove --yes local/my-repo` 5. **Bug**: The resource is deleted even though it is linked to a project. The spec requires this to fail with an error message telling the user to unlink first. ## Expected Behavior (from spec) ``` $ agents resource remove local/my-repo Error: Resource 'local/my-repo' is linked to 1 project(s). Use 'agents project unlink-resource' first. ``` ## Fix Required In the `resource_remove` function in `/app/src/cleveragents/cli/commands/resource.py`, add a check before deletion: ```python from cleveragents.infrastructure.database.models import ProjectResourceLinkModel # Check for project links project_link_count = ( session.query(ProjectResourceLinkModel) .filter_by(resource_id=res.resource_id) .count() ) if project_link_count > 0: console.print( f"[red]Cannot remove resource '{res.name or res.resource_id}': " f"linked to {project_link_count} project(s). " f"Use 'agents project unlink-resource' first.[/red]" ) raise typer.Abort() ``` **Code Location:** - `/app/src/cleveragents/cli/commands/resource.py` — `resource_remove` function This is a critical data integrity bug — resources linked to projects can be silently deleted, leaving orphaned project-resource links in the database. ## Subtasks - [ ] Add `ProjectResourceLinkModel` project-link count check in `resource_remove` before the deletion block - [ ] Add Behave unit test scenario: `resource remove` fails when resource is linked to a project - [ ] Add Behave unit test scenario: `resource remove` succeeds when resource has no project links - [ ] Add Robot Framework integration test: end-to-end verification of the guard (create project, link resource, attempt remove, expect failure) - [ ] Verify error message matches spec wording and suggests `agents project unlink-resource` - [ ] Update any relevant docstrings or inline comments referencing the spec line ## Definition of Done - [ ] `resource_remove` raises an error (does not delete) when the resource is linked to ≥1 project - [ ] Error message clearly names the resource, the number of linked projects, and the remediation command - [ ] All nox stages pass - [ ] Coverage >= 97% - [ ] Behave scenarios cover both the blocked and the allowed deletion paths - [ ] Robot Framework integration test confirms end-to-end behaviour --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.6.0 milestone 2026-04-05 16:31:23 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Critical — The specification requires that agents resource remove fails when a resource is linked to a project. This is a data integrity issue — removing linked resources could leave projects in an inconsistent state.
  • Milestone: v3.6.0 (already set)
  • Story Points: 3 — M — Requires adding a project link check before deletion and appropriate error handling. Estimated 4-8 hours.
  • MoSCoW: Must Have — Spec compliance for resource management. Data integrity cannot be compromised.
  • Parent Epic: #398 (Post-MVP Resources)

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Critical — The specification requires that `agents resource remove` fails when a resource is linked to a project. This is a data integrity issue — removing linked resources could leave projects in an inconsistent state. - **Milestone**: v3.6.0 (already set) - **Story Points**: 3 — M — Requires adding a project link check before deletion and appropriate error handling. Estimated 4-8 hours. - **MoSCoW**: Must Have — Spec compliance for resource management. Data integrity cannot be compromised. - **Parent Epic**: #398 (Post-MVP Resources) --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
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.

Blocks
#398 Epic: Post-MVP Resources
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3406
No description provided.