UAT: NamespacedProject domain model missing invariants and invariant_actor fields — stored via raw SQL bypass #3877

Open
opened 2026-04-06 07:05:52 +00:00 by freemo · 0 comments
Owner

Metadata

  • Branch: fix/namespaced-project-invariants-domain-model
  • Commit Message: fix(project): add invariants and invariant_actor to NamespacedProject domain model
  • Milestone: (backlog — see note below)
  • Parent Epic: #398

Background and Context

During UAT testing of the agents project create CLI command, the NamespacedProject domain model was found to be missing invariants and invariant_actor as first-class fields. The spec defines these as core fields for the agents project create command, and the Repository Pattern (ADR-007) requires all persistence to flow through the repository layer.

Current Behavior

  1. NamespacedProject model fields are: name, namespace, server, description, linked_resources, context_config, created_at, updated_atno invariants or invariant_actor fields.
  2. The CLI command agents project create stores invariants via _store_project_extras() which directly executes raw SQL (UPDATE ns_projects SET invariants_json = :inv_json), bypassing the repository entirely.
  3. NamespacedProjectRepository has no invariant handling.
  4. agents project show does not display invariants in its output.
  5. _project_spec_dict() helper does not include invariants in the returned dict, so JSON/YAML output formats also omit them.

Code locations:

  • src/cleveragents/domain/models/core/project.pyNamespacedProject class missing invariants: list[str] and invariant_actor: str | None fields
  • src/cleveragents/cli/commands/project.py_store_project_extras() function uses raw SQL instead of repository
  • src/cleveragents/cli/commands/project.pyshow() command and _project_spec_dict() helper omit invariants

Expected Behavior

Per the specification, agents project create supports:

  • --invariant TEXT: Invariant to attach to this project (repeatable). These invariants apply to all plans targeting this project.
  • --invariant-actor ACTOR: Invariant Reconciliation Actor for this project. Used to reconcile project-level invariants against global invariants for all plans targeting this project.

The NamespacedProject domain model must expose invariants and invariant_actor as first-class fields, consistent with the Repository Pattern (ADR-007). All persistence must flow through NamespacedProjectRepository.

Impact

  • Project-level invariants are stored but never surfaced to users via agents project show.
  • The raw SQL bypass violates ADR-007 (Repository Pattern) and makes invariants invisible to the domain model.
  • Plans targeting a project cannot reliably access project-level invariants through the domain model.

Subtasks

  • Add invariants: list[str] = Field(default_factory=list) to NamespacedProject in src/cleveragents/domain/models/core/project.py
  • Add invariant_actor: str | None = Field(default=None) to NamespacedProject in src/cleveragents/domain/models/core/project.py
  • Update NamespacedProjectRepository to persist and load invariants and invariant_actor fields
  • Remove _store_project_extras() raw SQL bypass from src/cleveragents/cli/commands/project.py; replace with repository calls
  • Update agents project show command to display invariants and invariant_actor in output
  • Update _project_spec_dict() helper to include invariants and invariant_actor in the returned dict (for JSON/YAML output)
  • Tests (Behave): Add/update BDD scenarios covering invariants and invariant_actor round-trip via repository
  • Tests (Behave): Add scenario verifying agents project show displays invariants
  • Tests (Robot): Add integration test for agents project create --invariant / --invariant-actor end-to-end
  • Verify coverage ≥97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • NamespacedProject exposes invariants: list[str] and invariant_actor: str | None as first-class Pydantic fields.
  • All invariant persistence flows through NamespacedProjectRepository — no raw SQL in CLI commands.
  • agents project show displays invariants and invariant_actor in all output formats (text, JSON, YAML).
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly (fix(project): add invariants and invariant_actor to NamespacedProject domain model), followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch fix/namespaced-project-invariants-domain-model.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage ≥ 97%.

Backlog note: This issue was discovered during autonomous operation
on milestone v3.6.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-uat-tester

## Metadata - **Branch**: `fix/namespaced-project-invariants-domain-model` - **Commit Message**: `fix(project): add invariants and invariant_actor to NamespacedProject domain model` - **Milestone**: *(backlog — see note below)* - **Parent Epic**: #398 ## Background and Context During UAT testing of the `agents project create` CLI command, the `NamespacedProject` domain model was found to be missing `invariants` and `invariant_actor` as first-class fields. The spec defines these as core fields for the `agents project create` command, and the Repository Pattern (ADR-007) requires all persistence to flow through the repository layer. ## Current Behavior 1. `NamespacedProject` model fields are: `name`, `namespace`, `server`, `description`, `linked_resources`, `context_config`, `created_at`, `updated_at` — **no `invariants` or `invariant_actor` fields**. 2. The CLI command `agents project create` stores invariants via `_store_project_extras()` which directly executes raw SQL (`UPDATE ns_projects SET invariants_json = :inv_json`), bypassing the repository entirely. 3. `NamespacedProjectRepository` has no invariant handling. 4. `agents project show` does **not** display invariants in its output. 5. `_project_spec_dict()` helper does **not** include invariants in the returned dict, so JSON/YAML output formats also omit them. **Code locations**: - `src/cleveragents/domain/models/core/project.py` — `NamespacedProject` class missing `invariants: list[str]` and `invariant_actor: str | None` fields - `src/cleveragents/cli/commands/project.py` — `_store_project_extras()` function uses raw SQL instead of repository - `src/cleveragents/cli/commands/project.py` — `show()` command and `_project_spec_dict()` helper omit invariants ## Expected Behavior Per the specification, `agents project create` supports: - `--invariant TEXT`: Invariant to attach to this project (repeatable). These invariants apply to all plans targeting this project. - `--invariant-actor ACTOR`: Invariant Reconciliation Actor for this project. Used to reconcile project-level invariants against global invariants for all plans targeting this project. The `NamespacedProject` domain model must expose `invariants` and `invariant_actor` as first-class fields, consistent with the Repository Pattern (ADR-007). All persistence must flow through `NamespacedProjectRepository`. ## Impact - Project-level invariants are stored but never surfaced to users via `agents project show`. - The raw SQL bypass violates ADR-007 (Repository Pattern) and makes invariants invisible to the domain model. - Plans targeting a project cannot reliably access project-level invariants through the domain model. ## Subtasks - [ ] Add `invariants: list[str] = Field(default_factory=list)` to `NamespacedProject` in `src/cleveragents/domain/models/core/project.py` - [ ] Add `invariant_actor: str | None = Field(default=None)` to `NamespacedProject` in `src/cleveragents/domain/models/core/project.py` - [ ] Update `NamespacedProjectRepository` to persist and load `invariants` and `invariant_actor` fields - [ ] Remove `_store_project_extras()` raw SQL bypass from `src/cleveragents/cli/commands/project.py`; replace with repository calls - [ ] Update `agents project show` command to display `invariants` and `invariant_actor` in output - [ ] Update `_project_spec_dict()` helper to include `invariants` and `invariant_actor` in the returned dict (for JSON/YAML output) - [ ] Tests (Behave): Add/update BDD scenarios covering `invariants` and `invariant_actor` round-trip via repository - [ ] Tests (Behave): Add scenario verifying `agents project show` displays invariants - [ ] Tests (Robot): Add integration test for `agents project create --invariant` / `--invariant-actor` end-to-end - [ ] Verify coverage ≥97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - `NamespacedProject` exposes `invariants: list[str]` and `invariant_actor: str | None` as first-class Pydantic fields. - All invariant persistence flows through `NamespacedProjectRepository` — no raw SQL in CLI commands. - `agents project show` displays invariants and invariant_actor in all output formats (text, JSON, YAML). - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly (`fix(project): add invariants and invariant_actor to NamespacedProject domain model`), followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch `fix/namespaced-project-invariants-domain-model`. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage ≥ 97%. > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.6.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-uat-tester
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#3877
No description provided.