UAT: InvariantService still uses in-memory storage — invariants lost between CLI invocations (issue #1022 closed but fix not merged) #3539

Open
opened 2026-04-05 19:05:37 +00:00 by freemo · 3 comments
Owner

Metadata

  • Branch: fix/invariant-service-db-persistence
  • Commit Message: fix(invariant): implement database persistence for InvariantService
  • Milestone: (none — see backlog note below)
  • Parent Epic: #394

Summary

Issue #1022 ("InvariantService uses in-memory storage only — invariants lost between CLI invocations") was closed on 2026-03-29, but the fix was never merged into the codebase. The InvariantService still uses in-memory dict storage with no database persistence.

Evidence

  1. No standalone InvariantModel table: src/cleveragents/infrastructure/database/models.py only contains ActionInvariantModel (child rows of actions) and PlanInvariantModel (child rows of plans). There is no standalone InvariantModel for the agents invariant add/list/remove CLI commands.

  2. No InvariantRepository: Searching src/cleveragents/infrastructure/database/repositories.py finds no InvariantRepository class.

  3. InvariantService uses in-memory dict: src/cleveragents/application/services/invariant_service.py line 57: self._invariants: dict[str, Invariant] = {} — no database interaction.

  4. TDD feature file still has @tdd_expected_fail tag: features/tdd_invariant_persistence.feature line 15 still has @tdd_expected_fail @tdd_issue @tdd_issue_1022 — the tests are still expected to fail, confirming the bug is not fixed.

  5. Container registration uses in-memory service: src/cleveragents/application/container.py lines 623-626 registers InvariantService as a Singleton with no UnitOfWork or repository dependency.

What Was Tested

Code analysis of:

  • src/cleveragents/application/services/invariant_service.py
  • src/cleveragents/infrastructure/database/models.py
  • src/cleveragents/infrastructure/database/repositories.py
  • src/cleveragents/application/container.py
  • features/tdd_invariant_persistence.feature

Expected Behavior

Per issue #1022 acceptance criteria (which were marked complete but not actually implemented):

  1. agents invariant add --project X "text" persists the invariant to the SQLite database
  2. agents invariant list --project X in a subsequent CLI invocation returns the persisted invariant
  3. agents invariant remove <ID> soft-deletes the invariant in the database

Actual Behavior

  1. agents invariant add --project X "text" stores invariant in process-local memory
  2. Process exits, invariant is garbage-collected
  3. agents invariant list --project X returns "No invariants found."

Impact

Critical: The entire agents invariant add/list/remove CLI surface is non-functional for real-world use. Users cannot persist invariants across CLI invocations, making the invariant system unusable.

Code Location

  • src/cleveragents/application/services/invariant_service.py line 57 (in-memory storage)
  • src/cleveragents/infrastructure/database/models.py (missing InvariantModel)
  • src/cleveragents/application/container.py lines 623-626 (no persistence wiring)
  • features/tdd_invariant_persistence.feature (TDD tests still expected to fail)

Relationship to Issue #1022

Issue #1022 was closed on 2026-03-29 with all acceptance criteria marked complete, but the code changes were never merged. This is a regression/tracking failure — the issue was closed prematurely.

Subtasks

  • Create InvariantModel SQLAlchemy model in src/cleveragents/infrastructure/database/models.py with fields for id, project, text, created_at, deleted_at (soft-delete)
  • Create InvariantRepository in src/cleveragents/infrastructure/database/repositories.py implementing add, list_by_project, and soft_delete operations
  • Refactor InvariantService to inject and use InvariantRepository via UnitOfWork instead of the in-memory dict
  • Wire InvariantService with InvariantRepository and UnitOfWork dependency in src/cleveragents/application/container.py
  • Remove @tdd_expected_fail and @tdd_issue_1022 tags from features/tdd_invariant_persistence.feature
  • Verify all BDD scenarios in tdd_invariant_persistence.feature pass without @tdd_expected_fail
  • Add/update Robot Framework integration test for cross-invocation persistence

Definition of Done

  • All subtasks above are checked
  • InvariantModel table exists in the SQLite schema and is created on startup
  • InvariantService reads and writes exclusively via InvariantRepository — no in-memory dict remains
  • agents invariant add --project X "text" followed by a fresh agents invariant list --project X invocation returns the persisted invariant
  • agents invariant remove <ID> soft-deletes the record (sets deleted_at); subsequent list does not return it
  • @tdd_expected_fail tags removed from features/tdd_invariant_persistence.feature; all scenarios pass
  • All nox stages pass (nox -e lint, nox -e typecheck, nox -e unit_tests, nox -e integration_tests)
  • Coverage >= 97%

Backlog note: This issue was discovered during autonomous UAT operation. Although it is Priority/Critical, the source milestone could not be determined automatically. It has been placed in the backlog for human review — please assign to the appropriate active milestone and expedite resolution given the critical impact on the invariant CLI surface.


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

## Metadata - **Branch**: `fix/invariant-service-db-persistence` - **Commit Message**: `fix(invariant): implement database persistence for InvariantService` - **Milestone**: *(none — see backlog note below)* - **Parent Epic**: #394 ## Summary Issue #1022 ("InvariantService uses in-memory storage only — invariants lost between CLI invocations") was closed on 2026-03-29, but the fix was never merged into the codebase. The `InvariantService` still uses in-memory `dict` storage with no database persistence. ## Evidence 1. **No standalone `InvariantModel` table**: `src/cleveragents/infrastructure/database/models.py` only contains `ActionInvariantModel` (child rows of actions) and `PlanInvariantModel` (child rows of plans). There is no standalone `InvariantModel` for the `agents invariant add/list/remove` CLI commands. 2. **No `InvariantRepository`**: Searching `src/cleveragents/infrastructure/database/repositories.py` finds no `InvariantRepository` class. 3. **`InvariantService` uses in-memory dict**: `src/cleveragents/application/services/invariant_service.py` line 57: `self._invariants: dict[str, Invariant] = {}` — no database interaction. 4. **TDD feature file still has `@tdd_expected_fail` tag**: `features/tdd_invariant_persistence.feature` line 15 still has `@tdd_expected_fail @tdd_issue @tdd_issue_1022` — the tests are still expected to fail, confirming the bug is not fixed. 5. **Container registration uses in-memory service**: `src/cleveragents/application/container.py` lines 623-626 registers `InvariantService` as a Singleton with no `UnitOfWork` or repository dependency. ## What Was Tested Code analysis of: - `src/cleveragents/application/services/invariant_service.py` - `src/cleveragents/infrastructure/database/models.py` - `src/cleveragents/infrastructure/database/repositories.py` - `src/cleveragents/application/container.py` - `features/tdd_invariant_persistence.feature` ## Expected Behavior Per issue #1022 acceptance criteria (which were marked complete but not actually implemented): 1. `agents invariant add --project X "text"` persists the invariant to the SQLite database 2. `agents invariant list --project X` in a subsequent CLI invocation returns the persisted invariant 3. `agents invariant remove <ID>` soft-deletes the invariant in the database ## Actual Behavior 1. `agents invariant add --project X "text"` stores invariant in process-local memory 2. Process exits, invariant is garbage-collected 3. `agents invariant list --project X` returns "No invariants found." ## Impact **Critical**: The entire `agents invariant add/list/remove` CLI surface is non-functional for real-world use. Users cannot persist invariants across CLI invocations, making the invariant system unusable. ## Code Location - `src/cleveragents/application/services/invariant_service.py` line 57 (in-memory storage) - `src/cleveragents/infrastructure/database/models.py` (missing `InvariantModel`) - `src/cleveragents/application/container.py` lines 623-626 (no persistence wiring) - `features/tdd_invariant_persistence.feature` (TDD tests still expected to fail) ## Relationship to Issue #1022 Issue #1022 was closed on 2026-03-29 with all acceptance criteria marked complete, but the code changes were never merged. This is a regression/tracking failure — the issue was closed prematurely. ## Subtasks - [ ] Create `InvariantModel` SQLAlchemy model in `src/cleveragents/infrastructure/database/models.py` with fields for `id`, `project`, `text`, `created_at`, `deleted_at` (soft-delete) - [ ] Create `InvariantRepository` in `src/cleveragents/infrastructure/database/repositories.py` implementing `add`, `list_by_project`, and `soft_delete` operations - [ ] Refactor `InvariantService` to inject and use `InvariantRepository` via `UnitOfWork` instead of the in-memory `dict` - [ ] Wire `InvariantService` with `InvariantRepository` and `UnitOfWork` dependency in `src/cleveragents/application/container.py` - [ ] Remove `@tdd_expected_fail` and `@tdd_issue_1022` tags from `features/tdd_invariant_persistence.feature` - [ ] Verify all BDD scenarios in `tdd_invariant_persistence.feature` pass without `@tdd_expected_fail` - [ ] Add/update Robot Framework integration test for cross-invocation persistence ## Definition of Done - [ ] All subtasks above are checked - [ ] `InvariantModel` table exists in the SQLite schema and is created on startup - [ ] `InvariantService` reads and writes exclusively via `InvariantRepository` — no in-memory `dict` remains - [ ] `agents invariant add --project X "text"` followed by a fresh `agents invariant list --project X` invocation returns the persisted invariant - [ ] `agents invariant remove <ID>` soft-deletes the record (sets `deleted_at`); subsequent `list` does not return it - [ ] `@tdd_expected_fail` tags removed from `features/tdd_invariant_persistence.feature`; all scenarios pass - [ ] All nox stages pass (`nox -e lint`, `nox -e typecheck`, `nox -e unit_tests`, `nox -e integration_tests`) - [ ] Coverage >= 97% > **Backlog note:** This issue was discovered during autonomous UAT operation. Although it is Priority/Critical, the source milestone could not be determined automatically. It has been placed in the backlog for human review — please assign to the appropriate active milestone and expedite resolution given the critical impact on the invariant CLI surface. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Critical — The invariant system is completely non-functional for real-world use. Invariants are lost between CLI invocations, making the entire agents invariant add/list/remove surface useless. Additionally, issue #1022 was closed prematurely without the fix being merged — this is a tracking failure that needs correction.
  • Milestone: v3.3.0 — The invariant system is part of the Decision Framework (Epic #394), which belongs to milestone v3.3.0 (Security & Decisions). Assigning accordingly.
  • Story Points: 5 — L — Requires creating a new SQLAlchemy model, a new repository class, refactoring the service to use UnitOfWork, updating container wiring, and removing TDD expected-fail tags. Well-scoped with a clear implementation path following existing patterns.
  • MoSCoW: Must Have — Invariants are a core part of the Decision Framework. The spec requires persistent invariant storage for plan validation and safety enforcement. Without persistence, the invariant system cannot fulfill its architectural purpose.
  • Parent Epic: #394 (Decision Framework)

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

Issue triaged by project owner: - **State**: Verified - **Priority**: Critical — The invariant system is completely non-functional for real-world use. Invariants are lost between CLI invocations, making the entire `agents invariant add/list/remove` surface useless. Additionally, issue #1022 was closed prematurely without the fix being merged — this is a tracking failure that needs correction. - **Milestone**: v3.3.0 — The invariant system is part of the Decision Framework (Epic #394), which belongs to milestone v3.3.0 (Security & Decisions). Assigning accordingly. - **Story Points**: 5 — L — Requires creating a new SQLAlchemy model, a new repository class, refactoring the service to use UnitOfWork, updating container wiring, and removing TDD expected-fail tags. Well-scoped with a clear implementation path following existing patterns. - **MoSCoW**: Must Have — Invariants are a core part of the Decision Framework. The spec requires persistent invariant storage for plan validation and safety enforcement. Without persistence, the invariant system cannot fulfill its architectural purpose. - **Parent Epic**: #394 (Decision Framework) --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Author
Owner

Issue verified and triaged:

  • Priority: Critical — the entire agents invariant add/list/remove CLI surface is non-functional for real-world use. Issue #1022 was closed prematurely without the fix being merged.
  • Milestone: Needs assignment — this bug spans invariant persistence which is core to v3.2.0 (M3: Decisions + Validations + Invariants). Recommend assigning to v3.2.0.
  • Story Points: 5 (L) — requires new SQLAlchemy model, repository, service refactor, and DI wiring.
  • Parent Epic: #394 (already linked)
  • Next step: This issue is now ready for implementation. Human review requested for milestone assignment.

Automated by CleverAgents Bot
Supervisor: Human Liaison | Agent: ca-human-liaison

Issue verified and triaged: - **Priority**: Critical — the entire `agents invariant add/list/remove` CLI surface is non-functional for real-world use. Issue #1022 was closed prematurely without the fix being merged. - **Milestone**: Needs assignment — this bug spans invariant persistence which is core to v3.2.0 (M3: Decisions + Validations + Invariants). Recommend assigning to v3.2.0. - **Story Points**: 5 (L) — requires new SQLAlchemy model, repository, service refactor, and DI wiring. - **Parent Epic**: #394 (already linked) - **Next step**: This issue is now ready for implementation. Human review requested for milestone assignment. --- **Automated by CleverAgents Bot** Supervisor: Human Liaison | Agent: ca-human-liaison
freemo added this to the v3.3.0 milestone 2026-04-05 19:33:38 +00:00
Author
Owner

Milestone Triage Decision: KEEPING in v3.3.0

This issue is being kept in v3.3.0 as it directly supports the core focus of Corrections + Subplans + Checkpoints.

Reasoning:

  • v3.3.0 focus: Essential corrections, subplan management, and checkpoint functionality
  • This issue: InvariantService persistence - essential infrastructure for corrections and plan validation
  • Impact: Core infrastructure blocking corrections and plan functionality

This is essential infrastructure that must work for corrections and subplan validation to function properly.

**Milestone Triage Decision: KEEPING in v3.3.0** This issue is being kept in v3.3.0 as it directly supports the core focus of Corrections + Subplans + Checkpoints. **Reasoning:** - v3.3.0 focus: Essential corrections, subplan management, and checkpoint functionality - This issue: InvariantService persistence - essential infrastructure for corrections and plan validation - Impact: Core infrastructure blocking corrections and plan functionality This is essential infrastructure that must work for corrections and subplan validation to function properly.
freemo removed this from the v3.3.0 milestone 2026-04-06 23:43:11 +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
#394 Epic: Decision Framework
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3539
No description provided.