UAT: bug(resource-registry): NamespacedProject.is_remote derived from namespace prefix instead of linked resource locality #2926

Open
opened 2026-04-05 02:50:48 +00:00 by freemo · 4 comments
Owner

Metadata

  • Commit Message: fix(resource-registry): derive project is_remote from linked resource locality
  • Branch: bugfix/project-is-remote-resource-locality
  • Parent Epic: #353
  • Milestone: v3.1.0

Background and Context

The spec defines project locality based on the resources it contains, not its namespace:

Local: Contains at least one local-only resource — can only execute on Client.
Remote: All resources are remotely accessible — can execute on Client or Server.

This distinction is critical for server-mode execution: the server can only execute plans on remote projects because it needs network access to all resources.

Current Behavior

In src/cleveragents/domain/models/core/project.py, NamespacedProject.is_remote is derived from the namespace/server prefix:

@property
def is_remote(self) -> bool:
    """Check if this project lives on a server."""
    return self.server is not None or self.namespace != DEFAULT_NAMESPACE

@property
def is_local(self) -> bool:
    """Check if this is a local-only project."""
    return self.namespace == DEFAULT_NAMESPACE and self.server is None

This means a project named local/my-project is always classified as "local" even if all its linked resources are remote (e.g., cloud databases, remote git repos). Conversely, a project named freemo/my-project is always classified as "remote" even if it has local filesystem resources.

Expected Behavior

Per the spec, is_remote should be derived from the locality of the project's linked resources:

  • A project is local if it contains at least one local-only resource.
  • A project is remote if all its resources are remotely accessible.

The is_remote / is_local properties should inspect the linked resources' locality (via the Resource Registry) rather than using the project's namespace prefix as a proxy.

Note: The namespace prefix (local/) is a naming convention, not a locality guarantee. A project can be named local/foo but link only remote resources.

Acceptance Criteria

  • NamespacedProject.is_remote returns True only when all linked resources are remotely accessible
  • NamespacedProject.is_local returns True when at least one linked resource is local-only
  • Projects with no linked resources have a defined default behavior (e.g., local by default)
  • Server-mode plan execution correctly rejects local projects
  • Existing tests updated; new tests cover resource-based locality classification

Subtasks

  • Update NamespacedProject.is_remote / is_local to inspect linked resource locality
  • Update Resource domain model to expose locality flag (local vs. remote)
  • Update server-mode plan execution guard to use the corrected is_remote
  • Add unit tests for locality classification
  • Run nox and ensure all sessions pass

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly.
  • 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.

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

## Metadata - **Commit Message**: `fix(resource-registry): derive project is_remote from linked resource locality` - **Branch**: `bugfix/project-is-remote-resource-locality` - **Parent Epic**: #353 - **Milestone**: v3.1.0 ## Background and Context The spec defines project locality based on the resources it contains, not its namespace: > **Local**: Contains at least one local-only resource — can only execute on Client. > **Remote**: All resources are remotely accessible — can execute on Client or Server. This distinction is critical for server-mode execution: the server can only execute plans on **remote** projects because it needs network access to all resources. ## Current Behavior In `src/cleveragents/domain/models/core/project.py`, `NamespacedProject.is_remote` is derived from the namespace/server prefix: ```python @property def is_remote(self) -> bool: """Check if this project lives on a server.""" return self.server is not None or self.namespace != DEFAULT_NAMESPACE @property def is_local(self) -> bool: """Check if this is a local-only project.""" return self.namespace == DEFAULT_NAMESPACE and self.server is None ``` This means a project named `local/my-project` is always classified as "local" even if all its linked resources are remote (e.g., cloud databases, remote git repos). Conversely, a project named `freemo/my-project` is always classified as "remote" even if it has local filesystem resources. ## Expected Behavior Per the spec, `is_remote` should be derived from the locality of the project's linked resources: - A project is **local** if it contains at least one local-only resource. - A project is **remote** if all its resources are remotely accessible. The `is_remote` / `is_local` properties should inspect the linked resources' locality (via the Resource Registry) rather than using the project's namespace prefix as a proxy. Note: The namespace prefix (`local/`) is a naming convention, not a locality guarantee. A project can be named `local/foo` but link only remote resources. ## Acceptance Criteria - [ ] `NamespacedProject.is_remote` returns `True` only when all linked resources are remotely accessible - [ ] `NamespacedProject.is_local` returns `True` when at least one linked resource is local-only - [ ] Projects with no linked resources have a defined default behavior (e.g., local by default) - [ ] Server-mode plan execution correctly rejects local projects - [ ] Existing tests updated; new tests cover resource-based locality classification ## Subtasks - [ ] Update `NamespacedProject.is_remote` / `is_local` to inspect linked resource locality - [ ] Update `Resource` domain model to expose locality flag (local vs. remote) - [ ] Update server-mode plan execution guard to use the corrected `is_remote` - [ ] Add unit tests for locality classification - [ ] Run `nox` and ensure all sessions pass ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly. - 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**. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-uat-tester
Author
Owner

Label compliance fix applied:

  • Added missing labels: Priority/Medium, State/Unverified, Type/Bug
  • Reason: Issue was missing all required labels per CONTRIBUTING.md. Inferred Type/Bug from the "UAT: bug" prefix. Applied Priority/Medium and State/Unverified as defaults.

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: ca-backlog-groomer

Label compliance fix applied: - Added missing labels: `Priority/Medium`, `State/Unverified`, `Type/Bug` - Reason: Issue was missing all required labels per CONTRIBUTING.md. Inferred `Type/Bug` from the "UAT: bug" prefix. Applied `Priority/Medium` and `State/Unverified` as defaults. --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: ca-backlog-groomer
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Confirmed
  • MoSCoW: Should Have

Valid finding verified during batch triage.


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

Issue triaged by project owner: - **State**: Verified - **Priority**: Confirmed - **MoSCoW**: Should Have Valid finding verified during batch triage. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
freemo added this to the v3.2.0 milestone 2026-04-05 04:49:30 +00:00
Author
Owner

Milestone compliance fix applied:

  • Assigned to milestone: v3.2.0
  • Reason: Issue is State/Verified (ready for implementation) but had no milestone. Issue body references Milestone: v3.1.0 which is no longer an active open milestone. Assigned to the earliest active milestone v3.2.0 as the appropriate target.

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: ca-backlog-groomer

Milestone compliance fix applied: - Assigned to milestone: `v3.2.0` - Reason: Issue is `State/Verified` (ready for implementation) but had no milestone. Issue body references `Milestone: v3.1.0` which is no longer an active open milestone. Assigned to the earliest active milestone `v3.2.0` as the appropriate target. --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: ca-backlog-groomer
freemo removed this from the v3.2.0 milestone 2026-04-06 22:28:35 +00:00
Author
Owner

This issue has been moved to the backlog as part of an aggressive grooming of the v3.2.0 milestone. It has been deemed non-critical for the minimal viability of the milestone and will be addressed in a future release.

This issue has been moved to the backlog as part of an aggressive grooming of the v3.2.0 milestone. It has been deemed non-critical for the minimal viability of the milestone and will be addressed in a future release.
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#2926
No description provided.