Commit Graph

1261 Commits

Author SHA1 Message Date
HAL9000 552dcb15b0 fix(plugins): remove duplicate step definitions and fix keyword context in feature
CI / lint (pull_request) Successful in 43s
CI / helm (pull_request) Successful in 45s
CI / build (pull_request) Successful in 53s
CI / quality (pull_request) Successful in 56s
CI / push-validation (pull_request) Successful in 55s
CI / typecheck (pull_request) Successful in 1m18s
CI / security (pull_request) Successful in 1m21s
CI / unit_tests (pull_request) Successful in 6m29s
CI / integration_tests (pull_request) Successful in 9m16s
CI / docker (pull_request) Successful in 1m41s
CI / coverage (pull_request) Successful in 12m27s
CI / status-check (pull_request) Successful in 3s
AmbiguousStep error caused all 8 features to error: plugin_executing_state_steps.py
re-defined 6 steps already present in plugin_architecture_steps.py:
- @then("a PluginError should be raised")
- @then("a PluginNotFoundError should be raised")
- @then('the plugin error message should contain "{text}"')
- @when('I attempt to deactivate the plugin "{name}"')
- @given("the PluginState enum is available")
- @then('it should have values ...')

Remove all duplicates, keeping only the 6 new steps unique to this feature.

Also fix the last scenario where `And I attempt to execute method on unknown plugin`
followed a `Given` step (so behave treated it as `given` context, not matching
the `@when` definition). Changed `And` to `When`.

ISSUES CLOSED: #5691
2026-06-04 20:36:52 -04:00
HAL9000 09d51237f0 fix(plugins): resolve step definition conflicts and update feature file 2026-06-04 20:36:52 -04:00
HAL9000 391c9f4fe7 fix(plugins): remove trailing whitespace in step definitions 2026-06-04 20:36:52 -04:00
HAL9000 9b5a723f96 fix(plugins): add missing step definitions for EXECUTING state tests 2026-06-04 20:36:52 -04:00
HAL9000 4139addbf5 fix(plugins): clean up unused imports in plugin_executing_state_steps.py
Remove unused imports (Any, given, PluginManager, PluginDescriptor) and
fix import ordering to satisfy ruff linting rules.
2026-06-04 20:36:52 -04:00
HAL9000 b0edcb53a4 fix(plugins): implement EXECUTING state in PluginManager lifecycle
- Added execute_plugin() method to PluginManager that properly sets PluginState.EXECUTING before calling a plugin method

- Transitions state back to ACTIVATED on success, or ERRORED on failure

- Completes the lifecycle state machine defined in PluginState enum

- Added BDD feature file features/plugin_executing_state.feature with scenarios covering state transitions

- Added step definitions in features/steps/plugin_executing_state_steps.py

ISSUES CLOSED: #5691
2026-06-04 20:36:52 -04:00
HAL9000 c56601eaf5 fix(lint): apply ruff format to anthropic/google/consolidated step files
CI / push-validation (pull_request) Successful in 30s
CI / lint (pull_request) Successful in 41s
CI / helm (pull_request) Successful in 46s
CI / build (pull_request) Successful in 51s
CI / quality (pull_request) Successful in 54s
CI / typecheck (pull_request) Successful in 1m16s
CI / security (pull_request) Successful in 1m25s
CI / unit_tests (pull_request) Successful in 5m36s
CI / integration_tests (pull_request) Successful in 10m20s
CI / docker (pull_request) Successful in 1m42s
CI / coverage (pull_request) Successful in 11m27s
CI / status-check (pull_request) Successful in 9s
2026-06-04 19:25:49 -04:00
HAL9000 9b6bedb463 fix(tests): resolve AmbiguousStep errors in provider BDD step files
CI / lint (pull_request) Failing after 43s
CI / helm (pull_request) Successful in 34s
CI / build (pull_request) Successful in 39s
CI / push-validation (pull_request) Successful in 27s
CI / quality (pull_request) Successful in 59s
CI / typecheck (pull_request) Successful in 1m20s
CI / security (pull_request) Successful in 1m49s
CI / unit_tests (pull_request) Successful in 5m57s
CI / coverage (pull_request) Has been skipped
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 11m25s
CI / status-check (pull_request) Failing after 4s
Extract shared Behave step definitions for LLM provider tests into
provider_shared_steps.py to eliminate duplicate @given registrations
that caused AmbiguousStep errors across anthropic, google, and openai
provider step files. Add missing step definitions to
consolidated_ai_models_providers_steps.py for consolidated feature
scenarios. Add @given decorator alongside @when for provider creation
steps used as Given steps in feature files.
2026-06-04 18:44:59 -04:00
HAL9000 8e44bebc90 feat: integrate Anthropic Claude and Google Gemini LLM backends 2026-06-04 18:44:59 -04:00
HAL9000 f50707fe05 fix(a2a): remove stale cleveragents.acp module
Add BDD tests to verify that cleveragents.acp is not importable and
the acp directory does not exist in the source tree. This ensures v3.6.0
deliverable #1 compliance: 'No acp references in public API'.

The acp module was renamed to a2a in issue #688, but stale __pycache__
files were left behind, allowing the module to still be imported from
bytecode. This test ensures this compliance persists.

ISSUES CLOSED: #5566
2026-06-04 17:43:33 -04:00
HAL9000 30c93bc95e fix(lsp,tui): repair five unit_test scenarios in CI
CI / lint (pull_request) Successful in 53s
CI / quality (pull_request) Successful in 48s
CI / typecheck (pull_request) Successful in 59s
CI / build (pull_request) Successful in 54s
CI / push-validation (pull_request) Successful in 39s
CI / helm (pull_request) Successful in 45s
CI / security (pull_request) Successful in 1m30s
CI / unit_tests (pull_request) Successful in 6m53s
CI / integration_tests (pull_request) Successful in 8m21s
CI / docker (pull_request) Successful in 1m36s
CI / coverage (pull_request) Successful in 8m54s
CI / status-check (pull_request) Successful in 2s
features/lsp_actor_service_wiring.feature scenarios "handles multiple
LSP servers" and "tool specs have correct schema": add an explicit
`| CAPABILITIES |` header to the capability tables. Behave treats the
first table row as the heading, so `| DIAGNOSTICS |` (the only row)
was being silently dropped, leaving the registered server with zero
capabilities and the adapter generating no tool specs.

features/steps/lsp_actor_service_steps.py: strip surrounding double
quotes from each entry in the comma-separated `fields` placeholder of
the `requires "..."` Then step so a feature line like `requires
"file_path", "line", "column"` resolves to the three unquoted field
names rather than `file_path"`, `"line"`, `"column"`.

features/steps/tui_persona_cycle_steps.py: include the surrounding
double quotes in the step pattern for "the registry last persona
should be set to ..." so the feature literal `"p2"` matches as `p2`
(without the quotes the placeholder captured `"p2"` and the equality
check against the registry value failed).

src/cleveragents/tui/persona/registry.py: reject absolute paths from
`resolve_export_path` and `resolve_import_path` with the messages the
"Persona export/import rejects absolute path targets" scenarios in
features/repl_input_modes.feature expect. The previous behaviour
silently accepted absolute paths, defeating the working-directory
sandboxing intent.

ISSUES CLOSED: #5663
2026-06-04 13:06:20 -04:00
HAL9000 8b066b6721 fix(lsp): preserve injected registry/lifecycle + deconflict persona test steps
LspRuntime.__init__ and LspActorService.__init__ used ``x or Y()`` to
default the registry/runtime kwargs. LspRegistry defines __len__, so an
empty instance is falsy, and the OR silently discarded a caller-supplied
empty registry — making the constructor parameter unusable. Replace with
explicit ``is None`` checks so callers can inject collaborators at
construction time. The previous workaround in lsp_actor_service_steps.py
reached into ``service._runtime._registry`` to compensate; the steps now
inject via the public LspRuntime + LspActorService constructors, no
private-attribute access.

Also deconflict three behave AmbiguousStep collisions in the bundled TUI
persona work that prevented behave-parallel from registering any step
definitions (the unit_tests gate was aborting at load time):

  * tui_persona_cycle_steps.py duplicated the registry-setup and active-
    persona steps already defined in tui_persona_system_steps.py — drop
    the duplicates and let the system file own them.
  * tui_persona_state_coverage_steps.py / .feature shared
    ``the registry last persona should be set to "X"`` with
    tui_persona_cycle_steps.py while asserting on a different mock —
    rename the coverage step to ``the mock registry set_last_persona
    should have been called with "X"``.
  * lsp_actor_service_steps.py registered the "actor bindings are
    activated" step under @when only; the deactivate scenario uses it
    after a ``Given/And`` chain, so behave inherited Given and the step
    was undefined. Register the same handler under both @given and
    @when.

Reformat three files that ``ruff format --check`` flagged
(tui_persona_cycle_steps.py, tui_persona_state_coverage_steps.py via
the rename, tui/persona/state.py) so the lint gate goes green.

ISSUES CLOSED: #5663
2026-06-04 13:06:20 -04:00
HAL9000 5dbcb2ed9c fix(tests): assert LSP server released after deactivation in lsp_actor_service_steps 2026-06-04 13:06:20 -04:00
HAL9000 dc315defb7 fix(lsp): wire LspRuntime and LspToolAdapter into actor execution
- Replace standard logging with structlog in LspActorService to fix typecheck errors (structlog uses keyword arguments for structured logging, not positional like stdlib logging)

- Fix LspServerConfig command field: use str not list[str] in test step definitions

- Add _MockLifecycleManager stub to prevent real LSP server process spawning during unit tests

- Rename duplicate step "a clean LSP registry" to "a clean LSP actor service registry" to avoid conflict with lsp_registry_steps.py

- Fix B904 lint error: raise ValueError from None in except clause
2026-06-04 13:06:20 -04:00
freemo 364946215b fix(lsp): wire LspRuntime and LspToolAdapter into actor execution
- Add LspActorService to manage LSP server lifecycle for actors
- Implement activate_actor_bindings() to start servers and generate tool specs
- Implement deactivate_actor_bindings() to release server references
- Add BDD tests for LSP actor service wiring
- Add step definitions for LSP actor service tests

Fixes #5663
2026-06-04 13:06:19 -04:00
freemo a1d905e681 feat(tui): implement PersonaRegistry with YAML load/save/list/cycle and PersonaState.cycle_persona() 2026-06-04 13:06:19 -04:00
HAL9000 7ed9c1279f fix(cli): resolve lint errors and step name conflict in command bus
CI / push-validation (pull_request) Successful in 33s
CI / helm (pull_request) Successful in 36s
CI / lint (pull_request) Successful in 44s
CI / quality (pull_request) Successful in 51s
CI / build (pull_request) Successful in 47s
CI / typecheck (pull_request) Successful in 1m10s
CI / security (pull_request) Successful in 1m27s
CI / unit_tests (pull_request) Successful in 6m15s
CI / docker (pull_request) Successful in 1m46s
CI / integration_tests (pull_request) Successful in 9m40s
CI / coverage (pull_request) Successful in 8m29s
CI / status-check (pull_request) Successful in 3s
- Replace deprecated typing imports (Dict, Callable, Generic) with
  collections.abc.Callable and built-in dict
- Convert Command from ABC to plain base class (B024: no abstract methods)
- Convert CommandHandler to PEP 695 type parameter syntax (UP046)
- Remove unused PlanService/ProjectService imports from command_registry
- Fix ruff format: blank line before nested defs in command_registry and steps
- Rename @then('a ValueError should be raised') to domain-specific suffix
  to avoid AmbiguousStep collision with lsp_registry_steps.py

ISSUES CLOSED: #8880
2026-06-04 11:47:32 -04:00
HAL9000 a185069070 refactor(cli): decouple CLI commands from application services via command bus
Implemented a command bus architecture to decouple CLI command handling from application services. Added command_bus.py with Command, CommandHandler, and CommandBus classes, and command_registry.py to register handlers. Introduced BDD tests at features/cli_command_bus_decoupling.feature and corresponding step definitions in features/steps/cli_command_bus_steps.py to verify the decoupling behavior.

ISSUES CLOSED: #8880
2026-06-04 11:47:32 -04:00
HAL9000 aee4e25853 fix(budget): fix type safety, formatting, and test correctness in CostTracker
CI / build (pull_request) Successful in 44s
CI / lint (pull_request) Successful in 52s
CI / quality (pull_request) Successful in 1m5s
CI / typecheck (pull_request) Successful in 1m19s
CI / helm (pull_request) Successful in 33s
CI / security (pull_request) Successful in 1m28s
CI / push-validation (pull_request) Successful in 26s
CI / unit_tests (pull_request) Successful in 4m42s
CI / integration_tests (pull_request) Successful in 9m38s
CI / docker (pull_request) Successful in 2m10s
CI / coverage (pull_request) Successful in 10m42s
CI / status-check (pull_request) Successful in 4s
- Convert CostRecord from @dataclass to Pydantic BaseModel (architecture policy)
- Replace declarative_base() + # type: ignore[misc] with DeclarativeBase subclass
- Use Mapped/mapped_column for proper SQLAlchemy 2.0 typed columns
- Remove all cast() calls — types now flow from Mapped[T] annotations
- Change timestamp column from String to DateTime; use datetime.now(UTC)
- Fix wrong expected totals in cost_tracker_service.feature (0.00035 → 0.00075)
- Fix step_check_entries_ids AttributeError: read plan_entries when session_entries absent
- Apply ruff format to both changed files

ISSUES CLOSED: #5248
2026-06-04 09:49:11 -04:00
HAL9000 d465389e9e feat(budget): implement CostTracker service for LLM spending tracking 2026-06-04 09:49:11 -04:00
HAL9000 36a6bd6011 fix(resources): resolve unit_tests failures and review blockers for virtual resource PR
CI / build (pull_request) Successful in 33s
CI / lint (pull_request) Successful in 56s
CI / helm (pull_request) Successful in 53s
CI / quality (pull_request) Successful in 57s
CI / typecheck (pull_request) Successful in 1m3s
CI / security (pull_request) Successful in 1m4s
CI / push-validation (pull_request) Successful in 25s
CI / unit_tests (pull_request) Successful in 5m21s
CI / integration_tests (pull_request) Successful in 10m15s
CI / docker (pull_request) Successful in 1m33s
CI / coverage (pull_request) Successful in 10m44s
CI / status-check (pull_request) Successful in 4s
Restores green unit_tests by removing the duplicate Pydantic virtual-resource
implementation that had no production consumers and was causing behave step
collisions, fixing parse-library step patterns that never matched, and giving
the failing-test scenarios concrete step definitions.

Changes:
- Remove unused parallel implementation `src/cleveragents/domain/models/core/
  virtual_resource.py`, its feature file `features/virtual_resource_types.feature`,
  and its step file `features/steps/virtual_resource_types_steps.py`. The
  canonical `src/cleveragents/resource/virtual.py` (re-exported by
  `src/cleveragents/resource/__init__.py`) is the only public API; the
  Pydantic copy had zero non-test consumers and its step file duplicated
  step text patterns (e.g., `the computed value should be ...`), triggering
  `behave.step_registry.AmbiguousStep` errors at module load.
- Fix `VirtualResource.__init__` name validation in
  `src/cleveragents/resource/virtual.py`: replace the
  `name.replace("-", "").replace("_", "").isalnum()` check with a single
  regex `^[a-zA-Z][a-zA-Z0-9_-]*$`. The old check accepted leading digits
  (e.g., `"123-invalid"` would strip the hyphen and pass `isalnum()`), so
  the "Reject invalid resource names" scenario was silently failing.
- Fix step patterns in `features/steps/resource_virtual_types_steps.py`:
  replace unsupported `{name!r}` parse-library syntax with literal-quoted
  `"{name}"` (confirmed via `parse.parse(...)` REPL that `!r` returns
  `None`); rename the over-broad `it should contain "{text}"` /
  `it should raise {error_type} with message containing "{message}"`
  patterns to specific forms that don't collide with steps in
  `execution_environment_steps.py` and `structural_validation_steps.py`;
  add try/except in the `When I compute the virtual resource` step so the
  exception-handling scenario can reach its `Then` step.
- Fix table headers in `features/resource_virtual_types.feature` so behave's
  table parser sees a proper `| name | value |` header row instead of
  treating the first data row as headers.
- Drop the now-unused E501 override for the deleted file from `pyproject.toml`.
- Add CHANGELOG.md entry under `[Unreleased]`.

Verified locally: unit_tests gate against `features/resource_virtual_types.feature`
passes 18/18 scenarios; lint and typecheck both green.

Refs: #8610
2026-06-04 04:23:37 -04:00
HAL9000 08e5fd4c01 fix(resources): resolve lint, type-safety, and test failures in virtual resource PR
- Remove # type: ignore from resource_virtual_types_steps.py (zero tolerance)
- Replace all eval() calls with ast.literal_eval() and _parse_lambda_body() helper
- Fix step mismatch: 'the complex computed value should be correct'
- Fix trailing whitespace and import ordering (W293, I001, RUF100)
- Fix B011 assert False -> raise AssertionError()
- Fix UP035/UP045/UP046 modernisation in domain model and resource virtual module
- Fix RUF022 __all__ sorting in resource/__init__.py
- Fix E501 long lines in virtual_resource.py via per-file-ignores
- Assign PR milestone to v3.6.0
2026-06-04 04:23:37 -04:00
HAL9000 abda05bd13 feat(resources): implement virtual resource type base class with examples
- Implement VirtualResource base class for abstract/computed resources
- Add MetricResource example for computed metrics
- Add APIEndpointResource example for API endpoints
- Implement comprehensive BDD tests for virtual resource types
- Full type annotations with Generic support
- Support for on-demand computation via compute_fn
- Support for kwargs passing to compute functions

Closes #8610
2026-06-04 04:23:37 -04:00
HAL9000 f6e84d384d feat(resources): implement virtual resource type base class for abstract/computed resources
- Implement VirtualResource base class with name, description, compute_fn, and metadata
- Implement MetricResource example for computed metrics with unit support
- Implement APIEndpointResource example for API endpoints with HTTP method support
- Add comprehensive BDD tests with 20+ scenarios covering all functionality
- Support on-demand computation via compute_fn callable
- Support metadata management with with_metadata() method
- Full type annotations and Pydantic validation
2026-06-04 04:23:37 -04:00
HAL9000 dfb4ae0bfe fix(governance): restore daily budget_type and move CostTrackingService out of core
CI / lint (pull_request) Successful in 42s
CI / helm (pull_request) Successful in 43s
CI / build (pull_request) Successful in 50s
CI / quality (pull_request) Successful in 53s
CI / typecheck (pull_request) Successful in 1m6s
CI / security (pull_request) Successful in 1m14s
CI / push-validation (pull_request) Successful in 25s
CI / unit_tests (pull_request) Successful in 6m12s
CI / coverage (pull_request) Failing after 1m5s
CI / integration_tests (pull_request) Successful in 10m23s
CI / docker (pull_request) Failing after 3m18s
CI / status-check (pull_request) Failing after 3s
The BudgetExhaustionEvent validator dropped "daily" from its allowed set, but
the legacy CostTracker in providers/cost_tracker.py still emits "daily" events
for the per-day budget path. That broke two cost_controls.feature scenarios
(BudgetExhaustionEvent accepts daily budget type; CostTracker blocks at 100% of
daily budget). Restore "daily" alongside "plan", "session", "org".

CostTrackingService lived in src/cleveragents/core/cost_tracking.py but imported
from cleveragents.domain.models.core.*, violating the architecture.feature
invariant "core package should be self-contained" (core may only import from
{core, config, shared}). Move the service to application/services/, where
domain imports are permitted, and update the lone caller in the BDD step file.

ISSUES CLOSED: #8609
2026-06-04 03:02:25 -04:00
HAL9000 4699d29057 fix(governance): resolve lint, unit_tests CI failures in cost budget tracking
CI / push-validation (pull_request) Successful in 29s
CI / lint (pull_request) Successful in 40s
CI / helm (pull_request) Successful in 44s
CI / quality (pull_request) Successful in 47s
CI / build (pull_request) Successful in 48s
CI / typecheck (pull_request) Successful in 1m11s
CI / security (pull_request) Successful in 1m13s
CI / unit_tests (pull_request) Failing after 5m29s
CI / coverage (pull_request) Has been skipped
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 9m43s
CI / status-check (pull_request) Failing after 3s
- Remove triple blank line in steps file (ruff format E303)
- Collapse multiline if conditions in cost_tracking.py (ruff format)
- Add BudgetExceededError to __all__ in exceptions.py
- Fix step_check_budget to pass context.org_accumulator instead of None
- Fix Three-tier scenario amounts so org budget fails first (session $200, org $100)
- Disambiguate @when step using {cost:f} type specifier to avoid AmbiguousStep
- Rename duplicate @then step to avoid conflict with lsp_registry_steps.py
- Add missing column header rows to Gherkin tables in feature file

ISSUES CLOSED: #8609
2026-06-04 02:28:50 -04:00
HAL9000 0d6896c55d fix(governance): correct budget_type labels and fix budget checks
- Use BudgetLevel.SESSION/ORG string values instead of hardcoded plan/daily in enforce_budget()
- Accept 'session' and 'org' as valid budget_type values in BudgetExhaustionEvent validator
- Add WARNING_THRESHOLD constant instead of magic 0.9 number
- Simplify nested ternary in check_budget() warning logic
- Remove unused OrgCostAccumulator import from cost_tracking.py
- Add missing BDD step definitions for org budget scenarios
- Fix budget_type check in step definitions to use BudgetLevel.SESSION.value

Closes #8609
2026-06-04 02:28:50 -04:00
HAL9000 09391787a4 feat(governance): implement cost and session budget tracking and enforcement
- Add BudgetExceededError exception for budget limit violations
- Implement CostTrackingService for managing cost tracking and budget enforcement
- Add comprehensive BDD tests for cost budget tracking and enforcement
- Support three-tier budget hierarchy (plan, session, organization)
- Track token usage and costs per provider
- Enforce budget limits with warning thresholds at 90% utilization
- Record budget exhaustion events for auditability
2026-06-04 02:28:50 -04:00
HAL9000 b502bb8542 test(coverage): add plain-format and bytes-size scenarios for project_context_set rendering
render_context_set_plain (~49 lines) was completely uncovered because no
existing test exercised the plain output path for context_set. Add a
coverage-boost scenario that uses format "plain" to cover those lines.

Also add a scenario with max_file_size=100 (not divisible by any binary
unit) to cover the _format_size bytes-fallback path (line 36 of
project_context_set.py).

ISSUES CLOSED: #6319
2026-06-03 17:30:22 -04:00
HAL9000 0aacec7845 fix(cli): address PR #6626 review blockers for context set output
- Fix ruff import ordering in project_context_cli_steps.py (yaml moved to third-party section)
- Remove unused noqa: F401 suppression in rendering/__init__.py
- Add *args, **kwargs to _test_format_output stub in coverage boost steps (fixes TypeError)
- Extract context-set step definitions into dedicated module (project_context_set_steps.py)
  to bring project_context_cli_steps.py under 500-line limit (469 -> 316 lines)
- Revert spec changes for context show/inspect/simulate message format (bare strings)
  to keep PR focused on issue #6319 (context set only),
2026-06-03 17:30:22 -04:00
HAL9000 388fc458c5 fix(cli): fix project context set JSON/YAML output structure (#6319)
Implemented spec-compliant JSON, YAML, plain, and rich outputs for `agents project context set`. Added BDD coverage verifying the new output structure across formats.\n\nISSUES CLOSED: #6319
2026-06-03 17:30:22 -04:00
HAL9000 6d4134938d feat(plans): implement configurable merge strategy for three-way merge
CI / lint (pull_request) Successful in 1m14s
CI / typecheck (pull_request) Successful in 1m29s
CI / security (pull_request) Successful in 1m30s
CI / quality (pull_request) Successful in 48s
CI / build (pull_request) Successful in 36s
CI / helm (pull_request) Successful in 41s
CI / push-validation (pull_request) Successful in 26s
CI / unit_tests (pull_request) Successful in 4m57s
CI / integration_tests (pull_request) Successful in 8m39s
CI / docker (pull_request) Successful in 1m45s
CI / coverage (pull_request) Successful in 9m4s
CI / status-check (pull_request) Successful in 3s
ISSUES CLOSED: #9559
2026-06-03 12:16:30 -04:00
HAL9000 7279ce64dd feat(plans): implement configurable merge strategy (prefer-parent, prefer-subplan, manual)
Implemented a configurable merge strategy framework for three-way merges.

- New module: src/cleveragents/domain/models/core/merge_strategy.py
  - MergeStrategy StrEnum with options: prefer-parent, prefer-subplan, manual
  - Helper methods: is_auto_resolve(), is_manual(), from_string()

- New module: src/cleveragents/domain/models/core/merge_strategy_service.py
  - MergeConflict class with __eq__ for value equality comparison
  - MergeStrategyService to apply strategies and resolve conflicts
  - Proper type annotations (dict, Any) with no unused imports

- BDD test suite: features/plan_merge_strategy.feature (8 scenarios)
- Step definitions: features/steps/plan_merge_strategy_steps.py

- Robot Framework integration tests: robot/merge_strategy.robot
- Helper script: robot/helper_merge_strategy.py

- Updated src/cleveragents/domain/models/core/__init__.py exports

ISSUES CLOSED: #9559
2026-06-03 12:16:30 -04:00
HAL9000 40e589eb55 test(e2e): add edge case scenarios for ACMS context CLI commands
CI / lint (pull_request) Successful in 39s
CI / push-validation (pull_request) Successful in 39s
CI / quality (pull_request) Successful in 55s
CI / helm (pull_request) Successful in 41s
CI / build (pull_request) Successful in 48s
CI / typecheck (pull_request) Successful in 1m13s
CI / security (pull_request) Successful in 1m18s
CI / unit_tests (pull_request) Successful in 4m43s
CI / docker (pull_request) Successful in 1m49s
CI / integration_tests (pull_request) Successful in 10m12s
CI / coverage (pull_request) Successful in 11m2s
CI / status-check (pull_request) Successful in 3s
Covers uncovered paths in acms_context.py:
- Empty view name rejection (context show error path)
- Clear without filters warning and auto-confirmation path

This improves code coverage by exercising the following functions:
- acms_context_show empty view validation branch (line 91-93)
- acms_context_clear no-filters warning with confirmation bypass (line 215-219)

Closes #9586
2026-06-03 11:24:21 -04:00
HAL9000 662e269485 fix(cli): resolve CI failures and reviewer feedback for ACMS context CLI commands
- Fix integration test failure: Context Show Validates Empty View Name
  - typer.Exit is click.Exit (RuntimeError subclass), not SystemExit
  - Robot helper now catches typer.Exit using exit_code attribute
  - Helper path insertion now always places clone src at sys.path[0]
    to prevent /app/src from shadowing the PR branch source
- Fix information disclosure: CleverAgentsError handler now logs
  exception internally via _logger.exception() and shows generic
  user-facing message instead of str(e)
- Fix budget utilization: use actual per-tier token counts instead
  of hot_count * 100 (fragment count * arbitrary factor)
- Fix type safety: _remove_fragments now uses _TierServiceProtocol
  instead of object, enabling proper static type checking
- Fix overly broad except: cancellation handled with early return
  instead of catching typer.Exit(0) in the except block
- Add broad glob pattern warning when --path matches > 50 entries
- Remove duplicate HAL 9000 entry from CONTRIBUTORS.md
- Fix Behave steps to catch typer.Exit in addition to SystemExit

ISSUES CLOSED: #9586
2026-06-03 11:24:21 -04:00
HAL9000 ea25627051 feat(cli): wire up ACMS context sub-app to main CLI entry point
The ACMS context CLI commands ('context show' / 'context clear') were fully
implemented in 'acms_context.py' with comprehensive tests, mocks, benchmarks,
and documentation — but the module was never imported or registered in
'cli/main.py'. This commit wires up the 'acms_context.app' Typer sub-app
so that 'agents acms context show' and 'agents acms context clear' are
actually accessible from the CLI.

Changes:
- Import acms_context in _register_subcommands()
- Register acms_context.app as the 'acms' sub-app on the main Typer app
- Add 'acms' to valid_cmds list in main() for fast-path validation
- Add 'acms context' entry to _print_basic_help() output
- Minor formatting cleanup applied by ruff

ISSUES CLOSED: #9586
Refs: #9675
2026-06-03 11:24:21 -04:00
HAL9000 c65a0726a8 feat(cli): implement context show and context clear CLI commands for ACMS - Closes #9586
- Rewrote production CLI to use real ContextTierService (get_scoped_view, get_all_fragments, evict_lru) instead of non-existent ACMSService
- Removed unused imports (Path, Panel, ScopedView) from production code
- Fixed all lint issues: trailing whitespace, import ordering, nested with statements
- Replaced typer.Abort() with typer.Exit(code=1) for error exits
- Added input validation for empty/whitespace view parameter
- Fixed error handling to use str(e) instead of e.message
- Added guards against negative budget values in _format_budget_utilization
- Added warning when clearing context with no filters (clear ALL)
- Removed module-level console side effect
- Moved mocks to features/mocks/acms_context_mocks.py per CONTRIBUTING.md
- Fixed test assertions to capture real CLI output (not placeholder)
- Fixed duplicate step definitions (AmbiguousStep errors)
- Fixed feature file step mismatch for tier count parameter
- Added Robot Framework integration tests in robot/acms_context_cli.robot
- Added performance benchmarks in benchmarks/acms_context_cli_bench.py
- Updated CHANGELOG.md with ACMS context CLI feature entry
- Updated CONTRIBUTORS.md with ACMS context CLI contribution

ISSUES CLOSED: #9586
2026-06-03 11:24:21 -04:00
HAL9000 acb484cf49 feat(cli): implement context show and context clear CLI commands for ACMS
ISSUES CLOSED: #9586
2026-06-03 11:24:21 -04:00
HAL9000 2165e82d72 fix(cli): add Progress, Timing, Execution Detail, and Cost panels to agents plan status output
Restore all five required Rich output panels to _print_lifecycle_plan():
- Plan Status panel: Processing State, Projects, Arguments, Automation Profile,
  actors (Strategy/Execution/Estimation/Invariant), Execution Environment,
  Created/Updated timestamps, Description, Definition of Done, DoD evaluation,
  Invariants, resume metadata, multi-project scopes, error message
- Progress panel: Strategize/Execute/Apply step indicators
- Timing panel: Started, Elapsed, ETA (using estimation_result when available),
  and all phase timestamps (Strategize Started/Completed, Execute Started/Completed,
  Applied At)
- Execution Detail panel: Sandbox, Tool Calls (N/A), Files Modified (N/A),
  Child Plans, Checkpoints
- Cost panel: Tokens Used, Cost So Far, Estimated Total Cost
- Footer: ✓ OK Status refreshed

Also fixes:
- tool_calls semantic bug: display N/A instead of total_tokens
- files_modified: display N/A (not available in cost_metadata)
- ETA calculation: use estimation_result.estimated_time_seconds or N/A
- In-function import: moved Plan as LifecyclePlan to top of file
- Import sorting: split aliased import per ruff isort rules

Adds BDD scenarios for all five panels in plan_lifecycle_cli_coverage.feature
with step definitions in plan_lifecycle_cli_coverage_steps.py.

Updates CHANGELOG.md with user-facing output changes.

ISSUES CLOSED: #9341
2026-06-03 09:01:44 -04:00
HAL9000 c957cf8cb1 fix(plan): unwrap format_output envelope in artifact JSON step assertions
The artifacts() method routes JSON through format_output() which wraps
the payload in a spec-required envelope {"data": ..., "status": ...}.
The two @tdd_issue_4253 step assertions were checking parsed["key"]
directly, but the actual fields live at parsed["data"]["key"].

Update step_artifacts_json_validation and step_artifacts_json_apply_summary
to extract parsed["data"] before asserting on validation_summary and
apply_summary respectively.

ISSUES CLOSED: #9084
2026-06-03 05:00:01 -04:00
HAL9000 8c8cbb771a fix(plan-lifecycle): align rollback contract with spec
- update PlanLifecycleService documentation for rollback phase/state semantics\n- add Behave scenarios covering checkpoint error propagation and supporting steps\n- adjust mock helpers to raise configured exceptions and keep scenario count accurate\n\nISSUES CLOSED: #3677
2026-06-03 03:22:59 -04:00
freemo 7fb3fc76c8 fix(plan-lifecycle): add rollback_plan method to PlanLifecycleService
- What was implemented
  - Added PLAN_ROLLED_BACK event type to the EventType enum at src/cleveragents/infrastructure/events/types.py to properly represent successful rollbacks in the domain model.
  - Implemented rollback_plan(plan_id: str, checkpoint_id: str) -> RollbackResult in PlanLifecycleService (src/cleveragents/application/services/plan_lifecycle_service.py) with:
    - Plan state validation: rejects rollback when the plan is in terminal APPLIED or CANCELLED states.
    - Delegation to CheckpointService.selective_rollback() to perform the actual rollback logic and obtain a RollbackResult.
    - Emission of PLAN_ROLLED_BACK as a domain event to reflect the completed rollback.
    - checkpoint_service is accepted as an optional constructor parameter; if not provided, a PlanError is raised to preserve backward compatibility.
  - Updated CLI behavior in src/cleveragents/cli/commands/plan.py so agents plan rollback routes through PlanLifecycleService.rollback_plan() rather than calling CheckpointService.selective_rollback() directly.
  - Updated PlanLifecycleService module docstring to include rollback_plan in the documented API.
  - Added Behave feature file features/plan_lifecycle_rollback.feature with 11 scenarios covering state validation, domain events, and delegation.
  - Added step implementations in features/steps/plan_lifecycle_rollback_steps.py to support the new scenarios.

- Key design decisions
  - rollback_plan returns RollbackResult (the same result type produced by CheckpointService.selective_rollback) so the CLI can display rollback details consistently.
  - Terminal states APPLIED and CANCELLED are disallowed for rollback to prevent inconsistent or invalid state transitions.
  - checkpoint_service is optional in the PlanLifecycleService constructor; when omitted (None), a PlanError is raised to retain backward compatibility while signaling explicit dependency requirements.
  - CLI UI remains powered by CheckpointService for metadata enrichment (e.g., confirmation prompts), but the actual rollback action is performed via PlanLifecycleService to ensure proper domain workflow and event emission.

- Technical implications
  - All rollback logic now flows through the domain service layer (PlanLifecycleService) to preserve invariants and emit domain events, rather than allowing ad-hoc UI routes to bypass service validation.
  - The UI can still retrieve checkpoint metadata for user confirmation, but the operation that modifies state uses the new rollback_plan pathway.
  - Tests and behavior coverage were expanded via the new Behave feature and step implementations to validate state handling, events, and delegation.

- Affected modules/components
  - src/cleveragents/infrastructure/events/types.py
  - src/cleveragents/application/services/plan_lifecycle_service.py
  - src/cleveragents/cli/commands/plan.py
  - PlanLifecycleService module docstring
  - features/plan_lifecycle_rollback.feature
  - features/steps/plan_lifecycle_rollback_steps.py

ISSUES CLOSED: #3677
2026-06-03 03:22:59 -04:00
HAL9000 1f1b135db7 fix(cli): add timing.started ISO timestamp to plan prompt JSON envelope
- Capture started_at timestamp using datetime.now(UTC) before service call
- Add timing.started field to JSON envelope with ISO 8601 format
- Update step definitions to verify timing.started is present and valid
- Remove @tdd_expected_fail tag from plan_prompt_command.feature scenario
- Remove unrelated files accidentally committed to repo root
- Move datetime import to top of plan_prompt_command_steps.py
- Add CHANGELOG.md entry under [Unreleased] > Fixed

ISSUES CLOSED: #9353
2026-06-03 03:03:14 -04:00
HAL9000 abd4e83baa fix(cli): add timing.started ISO timestamp to plan prompt JSON envelope
- Capture started_at timestamp using datetime.now(UTC) before service call
- Add timing.started field to JSON envelope with ISO 8601 format
- Update step definitions to verify timing.started is present and valid
- Remove @tdd_expected_fail tag from plan_prompt_command.feature scenario

Fixes #9353
2026-06-03 03:03:14 -04:00
HAL9000 c86db5afa9 style: ruff format fix for agent_task_memory_leak_fix_steps.py
CI / lint (pull_request) Successful in 41s
CI / helm (pull_request) Successful in 35s
CI / build (pull_request) Successful in 40s
CI / typecheck (pull_request) Successful in 1m0s
CI / quality (pull_request) Successful in 1m6s
CI / security (pull_request) Successful in 1m17s
CI / push-validation (pull_request) Successful in 24s
CI / unit_tests (pull_request) Successful in 4m53s
CI / docker (pull_request) Successful in 1m46s
CI / integration_tests (pull_request) Successful in 8m23s
CI / coverage (pull_request) Successful in 10m17s
CI / status-check (pull_request) Successful in 2s
Add blank line after docstring in step_basic_agent_setup to satisfy
ruff format check.
2026-06-03 00:53:20 -04:00
HAL9000 bb3ce1586b fix(agent): fix BDD test coordination and add CONTRIBUTORS entry
Fix the failing unit tests in agent_task_memory_leak_fix.feature by
replacing the broken event loop management with a persistent background
asyncio event loop running in a daemon thread. The original implementation
called asyncio.create_task() from synchronous Behave step code, which
requires a running event loop — causing RuntimeError: no running event loop.

The fix introduces a _BackgroundLoop class that keeps a dedicated asyncio
event loop alive in a background thread. All agent instantiation and
message sending now happens via asyncio.run_coroutine_threadsafe(), ensuring
the event loop is always running when asyncio.create_task() is called.

Also adds the missing step definition for 'I send {count:d} messages to
the agent' (without 'in rapid succession') to match the feature file.

Updates CONTRIBUTORS.md with the agent task memory leak fix contribution.

ISSUES CLOSED: #9044
2026-06-03 00:53:19 -04:00
HAL9000 9dd2ebb3f2 fix(agent): prune completed tasks from Agent._tasks to prevent unbounded growth
This fix addresses issue #9044 by adding a done callback to each asyncio.Task
created in the Agent._setup_processing_pipeline method. The callback removes
the task from the _tasks set upon completion, preventing unbounded memory
growth in long-lived agent instances.

The fix uses task.add_done_callback(self._tasks.discard) to ensure that
completed tasks are promptly removed from the set, allowing them to be
garbage collected. Using set.discard is safe as it never raises ValueError
on double-removal.

ISSUES CLOSED: #9044
2026-06-03 00:53:19 -04:00
HAL9000 e86a2a2c38 fix(a2a): format step definitions file
CI / quality (pull_request) Successful in 44s
CI / helm (pull_request) Successful in 37s
CI / build (pull_request) Successful in 38s
CI / lint (pull_request) Successful in 53s
CI / typecheck (pull_request) Successful in 1m1s
CI / push-validation (pull_request) Successful in 23s
CI / security (pull_request) Successful in 1m24s
CI / unit_tests (pull_request) Successful in 5m20s
CI / docker (pull_request) Successful in 1m48s
CI / integration_tests (pull_request) Successful in 7m52s
CI / coverage (pull_request) Successful in 9m49s
CI / status-check (pull_request) Successful in 3s
2026-06-02 23:33:52 -04:00
HAL9000 893debfeaf fix(a2a): add input validation for optional parameters in facade handlers
- Added input validation for namespace parameter in _handle_registry_list_tools in src/cleveragents/a2a/facade.py: If provided, must be a non-empty string; empty strings raise ValueError; non-string types raise TypeError
- Added input validation for type_name parameter in _handle_registry_list_resources in src/cleveragents/a2a/facade.py: If provided, must be a non-empty string; empty strings raise ValueError; non-string types raise TypeError
- Added input validation for arguments parameter in _handle_plan_create in src/cleveragents/a2a/facade.py: If provided, must be a dict; non-dict types raise TypeError
- Added input validation for created_by parameter in _handle_plan_create in src/cleveragents/a2a/facade.py: If provided, must be a non-empty string; empty strings raise ValueError; non-string types raise TypeError
- Added BDD feature file features/a2a_facade_optional_param_validation.feature with 17 scenarios covering all validation paths
- Added step definitions features/steps/a2a_facade_optional_param_validation_steps.py

ISSUES CLOSED: #9059
2026-06-02 23:33:52 -04:00
HAL9000 7b008193d6 fix(domain): correct invariant precedence chain to include action scope
CI / lint (pull_request) Successful in 41s
CI / typecheck (pull_request) Successful in 1m5s
CI / quality (pull_request) Successful in 1m2s
CI / security (pull_request) Successful in 1m12s
CI / build (pull_request) Successful in 35s
CI / helm (pull_request) Successful in 29s
CI / push-validation (pull_request) Successful in 24s
CI / unit_tests (pull_request) Successful in 5m7s
CI / docker (pull_request) Successful in 1m38s
CI / integration_tests (pull_request) Successful in 9m1s
CI / coverage (pull_request) Successful in 10m38s
CI / status-check (pull_request) Successful in 3s
The invariant precedence chain is four-tier per specification §92:
plan > action > project > global

This fix updates:
1. Module docstring in invariant.py to document the correct four-tier precedence
2. InvariantScope class docstring to reflect PLAN > ACTION > PROJECT > GLOBAL
3. merge_invariants() function to accept action_invariants parameter
4. InvariantSet.merge() class method to accept and pass action_invariants
5. InvariantService.get_effective_invariants() to collect and pass action invariants
6. BDD test steps to include action invariants in merge operations
7. Benchmark suite to include action invariants in performance tests
8. Robot Framework helper to pass action_invariants to merge functions
9. CHANGELOG.md entry under [Unreleased]/### Fixed section
10. CONTRIBUTORS.md entry documenting HAL 9000 contribution

All docstrings now correctly document the four-tier precedence chain,
and the merge logic properly handles action-scope invariants between
plan and project scopes.

ISSUES CLOSED: #9003
2026-06-02 22:45:08 -04:00