UAT: merge_invariants() only handles 3-tier precedence (plan > project > global) — ACTION tier missing from utility function #6488

Open
opened 2026-04-09 21:09:25 +00:00 by HAL9000 · 0 comments
Owner

Bug Report

Feature Area

Invariants & Automation Profiles

Spec Reference

docs/specification.md line 92:

A natural-language constraint on plan execution scoped to global, project, action, or plan level. The runtime precedence chain is four-tier: plan > action > project > global.

Expected Behavior

The merge_invariants() utility function in src/cleveragents/domain/models/core/invariant.py should accept and process all four tiers: plan, action, project, and global invariants, following the spec's stated precedence of plan > action > project > global.

Actual Behavior

The merge_invariants() function only accepts three parameters and handles three tiers:

def merge_invariants(
    plan_invariants: list[Invariant],
    project_invariants: list[Invariant],
    global_invariants: list[Invariant],
) -> list[Invariant]:

The ACTION tier is completely absent. The function iterates:

for inv_list in (plan_invariants, project_invariants, global_invariants):

This means action-scoped invariants are never included in the merged effective set when using this utility function.

Runtime Verification

from cleveragents.domain.models.core.invariant import merge_invariants, Invariant, InvariantScope

inv_plan = Invariant(text='Plan constraint', scope=InvariantScope.PLAN, source_name='plan1')
inv_action = Invariant(text='Action constraint', scope=InvariantScope.ACTION, source_name='action1')
inv_project = Invariant(text='Project constraint', scope=InvariantScope.PROJECT, source_name='proj1')
inv_global = Invariant(text='Global constraint', scope=InvariantScope.GLOBAL, source_name='system')

# merge_invariants only accepts 3 args - action invariants cannot be passed
result = merge_invariants([inv_plan], [inv_project], [inv_global])
# Result: ['plan', 'project', 'global'] - ACTION MISSING

Code Location

  • src/cleveragents/domain/models/core/invariant.pymerge_invariants() function (line ~166)
  • src/cleveragents/domain/models/core/invariant.pyInvariantSet.merge() class method (line ~130)

Note

The InvariantReconciliationActor in src/cleveragents/actor/reconciliation.py correctly handles all 4 tiers. However, merge_invariants() and InvariantSet.merge() are used elsewhere (e.g., InvariantService.get_effective_invariants()) and are broken.

Severity

Critical — The 4-tier invariant precedence chain is a core spec requirement. Action-scoped invariants are silently dropped when using the merge_invariants() utility.


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

## Bug Report ### Feature Area Invariants & Automation Profiles ### Spec Reference `docs/specification.md` line 92: > A natural-language constraint on plan execution scoped to global, project, action, or plan level. The runtime precedence chain is four-tier: **plan > action > project > global**. ### Expected Behavior The `merge_invariants()` utility function in `src/cleveragents/domain/models/core/invariant.py` should accept and process all four tiers: plan, action, project, and global invariants, following the spec's stated precedence of `plan > action > project > global`. ### Actual Behavior The `merge_invariants()` function only accepts **three** parameters and handles **three** tiers: ```python def merge_invariants( plan_invariants: list[Invariant], project_invariants: list[Invariant], global_invariants: list[Invariant], ) -> list[Invariant]: ``` The ACTION tier is completely absent. The function iterates: ```python for inv_list in (plan_invariants, project_invariants, global_invariants): ``` This means action-scoped invariants are **never included** in the merged effective set when using this utility function. ### Runtime Verification ```python from cleveragents.domain.models.core.invariant import merge_invariants, Invariant, InvariantScope inv_plan = Invariant(text='Plan constraint', scope=InvariantScope.PLAN, source_name='plan1') inv_action = Invariant(text='Action constraint', scope=InvariantScope.ACTION, source_name='action1') inv_project = Invariant(text='Project constraint', scope=InvariantScope.PROJECT, source_name='proj1') inv_global = Invariant(text='Global constraint', scope=InvariantScope.GLOBAL, source_name='system') # merge_invariants only accepts 3 args - action invariants cannot be passed result = merge_invariants([inv_plan], [inv_project], [inv_global]) # Result: ['plan', 'project', 'global'] - ACTION MISSING ``` ### Code Location - `src/cleveragents/domain/models/core/invariant.py` — `merge_invariants()` function (line ~166) - `src/cleveragents/domain/models/core/invariant.py` — `InvariantSet.merge()` class method (line ~130) ### Note The `InvariantReconciliationActor` in `src/cleveragents/actor/reconciliation.py` correctly handles all 4 tiers. However, `merge_invariants()` and `InvariantSet.merge()` are used elsewhere (e.g., `InvariantService.get_effective_invariants()`) and are broken. ### Severity **Critical** — The 4-tier invariant precedence chain is a core spec requirement. Action-scoped invariants are silently dropped when using the `merge_invariants()` utility. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.2.0 milestone 2026-04-09 21:09:56 +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.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#6488
No description provided.