UAT: agents resource unlink-child does not prevent unlinking auto-discovered DAG links #2051

Open
opened 2026-04-03 03:42:23 +00:00 by freemo · 0 comments
Owner

Metadata

  • Branch: fix/resource-unlink-child-auto-discovered-guard
  • Commit Message: fix(resource): prevent manual unlinking of auto-discovered DAG resource links
  • Milestone: v3.7.0
  • Parent Epic: #398

Background and Context

During UAT testing of the resource management feature area, it was discovered that the agents resource unlink-child command allows users to manually unlink parent-child resource links that were created by auto-discovery. This violates the specification, which explicitly states that auto-discovered links are immutable from the user's perspective.

Per docs/specification.md (Resource DAG section):

"Auto-discovered links cannot be manually unlinked."

Auto-discovered resources (e.g., a devcontainer-instance discovered when a git-checkout or fs-directory resource contains a .devcontainer/ directory) are managed entirely by the auto-discovery subsystem. Allowing users to manually remove these links breaks the integrity of the Resource DAG and can cause inconsistencies between the actual filesystem/environment state and the resource registry.

Current Behavior

In src/cleveragents/application/services/_resource_registry_dag.py, the unlink_child() method (lines ~100–140) does not check whether the link being removed was created by auto-discovery. It simply locates the ResourceLinkModel entry and deletes it, regardless of whether the child resource has auto_discovered=True.

As a result, a user can run:

agents resource unlink-child <parent-ulid> <child-ulid>

and successfully remove an auto-discovered link — which should be rejected.

Expected Behavior

The unlink_child() method must inspect the child resource's auto_discovered flag before proceeding. If auto_discovered is True, the method must raise a ValidationError with the message:

"Cannot manually unlink auto-discovered resource link"

The CLI command resource_unlink_child() in src/cleveragents/cli/commands/resource.py must catch this ValidationError and surface it to the user with a clear, human-readable error message (e.g., via a rich error panel), then exit with a non-zero status code.

Acceptance Criteria

  • unlink_child() queries the child resource's auto_discovered flag before deleting the link.
  • If auto_discovered is True, unlink_child() raises ValidationError("Cannot manually unlink auto-discovered resource link") and does not delete the link.
  • If auto_discovered is False (or None), unlink_child() proceeds as before.
  • The CLI resource_unlink_child() command catches the ValidationError and displays a user-friendly error message, exiting with a non-zero status code.
  • A Behave BDD scenario verifies that unlink-child fails when the child resource is auto-discovered.
  • A Behave BDD scenario verifies that unlink-child succeeds for manually-linked resources (regression guard).
  • All nox default sessions pass with no errors.
  • Unit test coverage remains ≥ 97%.

Supporting Information

  • Code locations:
    • src/cleveragents/application/services/_resource_registry_dag.pyunlink_child() method (~lines 100–140)
    • src/cleveragents/cli/commands/resource.pyresource_unlink_child() CLI command
  • Spec reference: docs/specification.md — Resource DAG section: "Auto-discovered links cannot be manually unlinked."
  • Related epic: #398 — Epic: Post-MVP Resources

Subtasks

  • Add auto-discovered guard in unlink_child(): query the child resource's auto_discovered flag; if True, raise ValidationError with message "Cannot manually unlink auto-discovered resource link"
  • Update CLI resource_unlink_child() to catch the new ValidationError and surface it with a user-friendly rich error message and non-zero exit code
  • Tests (Behave): Add BDD scenario verifying that unlink-child fails when the child resource is auto-discovered
  • Tests (Behave): Add BDD scenario verifying that unlink-child succeeds for manually-linked resources (regression guard)
  • Verify coverage ≥ 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • unlink_child() rejects attempts to unlink auto-discovered links with a ValidationError and a clear error message.
  • The CLI resource_unlink_child() command surfaces the error with a user-friendly message and exits with a non-zero status code.
  • All Behave BDD scenarios for this fix pass (both the failure case for auto-discovered links and the success case for manual links).
  • All nox stages pass (lint, typecheck, unit_tests, integration_tests, coverage_report).
  • Coverage ≥ 97%.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.

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

## Metadata - **Branch**: `fix/resource-unlink-child-auto-discovered-guard` - **Commit Message**: `fix(resource): prevent manual unlinking of auto-discovered DAG resource links` - **Milestone**: v3.7.0 - **Parent Epic**: #398 ## Background and Context During UAT testing of the resource management feature area, it was discovered that the `agents resource unlink-child` command allows users to manually unlink parent-child resource links that were created by auto-discovery. This violates the specification, which explicitly states that auto-discovered links are immutable from the user's perspective. Per `docs/specification.md` (Resource DAG section): > "Auto-discovered links cannot be manually unlinked." Auto-discovered resources (e.g., a `devcontainer-instance` discovered when a `git-checkout` or `fs-directory` resource contains a `.devcontainer/` directory) are managed entirely by the auto-discovery subsystem. Allowing users to manually remove these links breaks the integrity of the Resource DAG and can cause inconsistencies between the actual filesystem/environment state and the resource registry. ## Current Behavior In `src/cleveragents/application/services/_resource_registry_dag.py`, the `unlink_child()` method (lines ~100–140) does not check whether the link being removed was created by auto-discovery. It simply locates the `ResourceLinkModel` entry and deletes it, regardless of whether the child resource has `auto_discovered=True`. As a result, a user can run: ``` agents resource unlink-child <parent-ulid> <child-ulid> ``` and successfully remove an auto-discovered link — which should be rejected. ## Expected Behavior The `unlink_child()` method must inspect the child resource's `auto_discovered` flag before proceeding. If `auto_discovered` is `True`, the method must raise a `ValidationError` with the message: > "Cannot manually unlink auto-discovered resource link" The CLI command `resource_unlink_child()` in `src/cleveragents/cli/commands/resource.py` must catch this `ValidationError` and surface it to the user with a clear, human-readable error message (e.g., via a rich error panel), then exit with a non-zero status code. ## Acceptance Criteria - [ ] `unlink_child()` queries the child resource's `auto_discovered` flag before deleting the link. - [ ] If `auto_discovered` is `True`, `unlink_child()` raises `ValidationError("Cannot manually unlink auto-discovered resource link")` and does **not** delete the link. - [ ] If `auto_discovered` is `False` (or `None`), `unlink_child()` proceeds as before. - [ ] The CLI `resource_unlink_child()` command catches the `ValidationError` and displays a user-friendly error message, exiting with a non-zero status code. - [ ] A Behave BDD scenario verifies that `unlink-child` fails when the child resource is auto-discovered. - [ ] A Behave BDD scenario verifies that `unlink-child` succeeds for manually-linked resources (regression guard). - [ ] All `nox` default sessions pass with no errors. - [ ] Unit test coverage remains ≥ 97%. ## Supporting Information - **Code locations**: - `src/cleveragents/application/services/_resource_registry_dag.py` — `unlink_child()` method (~lines 100–140) - `src/cleveragents/cli/commands/resource.py` — `resource_unlink_child()` CLI command - **Spec reference**: `docs/specification.md` — Resource DAG section: *"Auto-discovered links cannot be manually unlinked."* - **Related epic**: #398 — Epic: Post-MVP Resources ## Subtasks - [ ] Add auto-discovered guard in `unlink_child()`: query the child resource's `auto_discovered` flag; if `True`, raise `ValidationError` with message `"Cannot manually unlink auto-discovered resource link"` - [ ] Update CLI `resource_unlink_child()` to catch the new `ValidationError` and surface it with a user-friendly rich error message and non-zero exit code - [ ] Tests (Behave): Add BDD scenario verifying that `unlink-child` fails when the child resource is auto-discovered - [ ] Tests (Behave): Add BDD scenario verifying that `unlink-child` succeeds for manually-linked resources (regression guard) - [ ] Verify coverage ≥ 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - [ ] `unlink_child()` rejects attempts to unlink auto-discovered links with a `ValidationError` and a clear error message. - [ ] The CLI `resource_unlink_child()` command surfaces the error with a user-friendly message and exits with a non-zero status code. - [ ] All Behave BDD scenarios for this fix pass (both the failure case for auto-discovered links and the success case for manual links). - [ ] All nox stages pass (lint, typecheck, unit_tests, integration_tests, coverage_report). - [ ] Coverage ≥ 97%. - [ ] A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation. - [ ] The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly. - [ ] The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.7.0 milestone 2026-04-03 03:42:28 +00:00
freemo self-assigned this 2026-04-03 16:58:13 +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.

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