feat(invariants): implement Invariant data model and database schema #11037

Closed
HAL9000 wants to merge 6 commits from pr-8701-invariant-model into master

6 Commits

Author SHA1 Message Date
HAL9000 5369524206 fix(lint): resolve remaining ruff violations in PR #11037
CI / push-validation (pull_request) Successful in 29s
CI / helm (pull_request) Successful in 38s
CI / build (pull_request) Successful in 1m6s
CI / lint (pull_request) Successful in 1m32s
CI / quality (pull_request) Successful in 1m43s
CI / security (pull_request) Successful in 1m51s
CI / typecheck (pull_request) Successful in 1m54s
CI / integration_tests (pull_request) Successful in 4m29s
CI / unit_tests (pull_request) Failing after 5m48s
CI / coverage (pull_request) Has been skipped
CI / docker (pull_request) Has been skipped
CI / status-check (pull_request) Failing after 2s
F401: Remove unused datetime imports (UTC, datetime) from
  features/steps/invariant_model_steps.py and robot/helper_invariant_model.py
  (auto-populated timestamps removed explicit values per B2 fix).

RUF022: Sort InvariantModel alphabetically in __all__ within
  src/cleveragents/infrastructure/database/__init__.py.

All CI lint violations resolved. Closes review blockers from #11037.
2026-05-17 17:43:25 +00:00
HAL9000 24f0250c93 fix(invariants): resolve PR #11037 review blockers — fix created_at type, auto-populate, and strict type-safety
Fixes blocking issues from latest PR review (#9007,HAL9001):

B1: Switched created_at and updated_at columns in InvariantModel
       from String(30) to DateTime with server-side defaults so that ISO-8601
       timestamps are not truncated (String(30) holds only 30 chars; modern
       ISO timestamps like "2026-05-16T03:49:01.679543+00:00" need ~41 chars).

B2: Added default=datetime.now(tz=UTC) and server_default to created_at
       and updated_at columns so timestamps are auto-populated on insert,
       matching issue #8524 acceptance criteria that states created_at is
       "auto-populated on insert".

B3: Removed __allow_unmapped__ = True from InvariantModel.  This flag
       was incompatible with strict type-safety requirements — unmapped
       columns cannot be reliably resolved by Pyright.  The model now uses
       explicit SQLAlchemy column declarations that are fully typed.

S3: Removed op.create_index("ix_invariants_updated_at", ...) from the
     Alembic migration since an index on updated_at was not specified in
     acceptance criteria.
2026-05-17 17:43:25 +00:00
HAL9000 8b03411833 fix(invariants): align InvariantModel with codebase ULID and timestamp standards
InvariantModel used String(36) UUID-style PK instead of the codebase-
standard ULID (String(26)), and was missing the required updated_at
column present on all peer entity models.  Updated both the ORM class
and the migration DDL to match conventions:

- PK: String(36) → String(26) for ULID compatibility with resource_id,
  decision_id, checkpoint_id, job_id, etc.
- Added updated_at column (String(30)) matching NamespacedProjectModel,
  ResourceLinkModel and other entity tables
- Updated migration `m3_001_invariants_table` DDL to mirror ORM model
- Added index on updated_at for audit-query performance
2026-05-17 17:43:25 +00:00
HAL9000 08b686e0e5 fix(invariants): address review feedback for PR #11037
- Fix Ruff E303: reduce blank lines before InvariantModel to 2 (models.py)
- Add type ignore on behave.runner import (invariant_model_steps.py)
- Add CheckConstraint('description != ''') on InvariantModel and migration
- Fix migration chain: update down_revision to reference latest head m9_003

Also removes deleted file stdio_transport.py that was part of merged-in PR changes.

Addresses review items #1, #2, #6, #8 from HAL9001.
2026-05-17 17:43:25 +00:00
HAL9000 0c1c07bd85 fix(compliance): correct Invariant entry in CONTRIBUTORS.md — use proper single-* format and place at end-of-file with PR #8701 / issue #8524 reference
The previous commit (de996894) corrupted the contributors entry:
- Used double ** prefix instead of single *
- Placed it mid-stream replacing a valid entry instead of adding to end

ISSUES CLOSED: #8524
2026-05-17 17:43:25 +00:00
HAL9000 300c00acd9 feat(invariants): implement Invariant data model and database schema
Implement the Invariant SQLAlchemy ORM model in
cleveragents.infrastructure.database.models.InvariantModel with fields
id (UUID), description (text), created_at (timestamp), and is_active (bool).

Added Alembic migration m3_001_invariants_table that creates the
invariants table with an index on is_active for efficient active-invariant
queries. Includes both upgrade and downgrade paths.

BDD Behave unit tests cover invariant creation, persistence, filtering by
is_active, deactivation, and schema validation. Robot Framework integration
tests provide smoke testing of the implementation contract.

ISSUES CLOSED: #8524
2026-05-17 11:25:07 +00:00