Commit Graph

1442 Commits

Author SHA1 Message Date
brent.edwards 1ec2200e34 test(e2e): verify M6 success criteria — Firefox-scale autonomous porting
Robot Framework E2E test suite exercising the complete M6 success
criteria verification sequence:

- Porting action creation from YAML config via CLI
- Plan use + execute via CLI with mocked lifecycle service
- Hierarchical decomposition: 4+ levels (root + L1-L4 = 21+ plans)
- Decision correction recomputes only affected subtree (CorrectionImpact)
- Parallel execution scales to 15 concurrent subplans (10+ required)
- Realistic porting task: full ACTION → STRATEGIZE → EXECUTE → APPLY
  lifecycle with 10 subplans completing autonomously
- Plan apply transitions to APPLIED terminal state
- SubplanFailureHandler retry/stop-others logic verification
- SubplanConfig supports all execution modes and merge strategies
- Decision tree structure: PROMPT_DEFINITION root with
  SUBPLAN_PARALLEL_SPAWN children and superseded_by flow

Ten subcommands in the Python helper, each printing a sentinel
string on success. All subcommands verified passing locally.

Closes #407
2026-02-26 19:27:53 +00:00
brent.edwards 93f2d396a1 Merge pull request 'test: consolidated Brent QA batch — issues #179, #180, #404, #405, #187' (#442) from develop-brent-5 into master
Reviewed-on: cleveragents/cleveragents-core#442
Reviewed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
2026-02-26 16:54:21 +00:00
brent.edwards fd1612c38f test(e2e): verify M5 success criteria — ACMS and large-project context
Robot Framework E2E test suite exercising the complete M5 success
criteria verification sequence:

- Large project creation with 10,000+ simulated files
- Resource registration and linking to a project
- Indexing verification (resource linked, project shows correctly)
- Context tier management (hot/warm/cold) via ContextConfig
- ACMS v1 context policy set/show with persistence round-trip
- Phase view inheritance (default → strategize → execute → apply)
- Scoped context output per ACMS phase with narrowing size limits
- Policy clear and inheritance fallback
- ContextView validation rules (size limits, VALID_PHASES)

Nine subcommands in the Python helper, each printing a sentinel
string on success. All subcommands verified passing locally.

Closes #406
2026-02-26 16:32:01 +00:00
brent.edwards ffdd2f2b19 Merge branch 'master' into develop-brent-5 2026-02-26 16:14:07 +00:00
brent.edwards 32b81793a2 refactor(test): rename decision persistence files to avoid conflict with master
Rename our serialization-focused decision persistence suites to
*_serialization to avoid add/add conflicts with the repository-based
decision persistence suites that landed on master independently:

- decision_persistence.feature -> decision_persistence_serialization.feature
- decision_persistence_steps.py -> decision_persistence_serialization_steps.py
- decision_persistence_bench.py -> decision_persistence_serialization_bench.py
- decision_persistence.robot -> decision_persistence_serialization.robot
- helper_decision_persistence.py -> helper_decision_persistence_serialization.py

Updated robot helper path, step docstring, and testing.md references.
2026-02-26 16:13:44 +00:00
hamza.khyari 074f884f14 Merge pull request 'fix(security): close async resources and leaks' (#435) from feature/m4-security-async-cleanup into master
Reviewed-on: cleveragents/cleveragents-core#435
2026-02-26 15:19:16 +00:00
aditya 76db58414a Merge branch 'master' into feature/m3-agent-skills-loader 2026-02-26 14:51:41 +00:00
aditya f8bc02869a Merge branch 'master' into feature/m3-agent-skills-loader 2026-02-26 14:43:52 +00:00
aditya d0337a0881 fix(skill): eliminate Any from agent_skills_loader type signatures
Replace dict[str, Any] with a private _YamlMapping type alias
(dict[str, object]) in AgentSkillSpec Pydantic fields and all
internal helper function signatures. Add isinstance guard for
allowed-tools list iteration to satisfy pyright.

Refs: #160
2026-02-26 14:40:44 +00:00
khyari hamza c406781b86 fix(security): address PR #435 review feedback
P0: reject register() after close_all() with RuntimeError.
P1: catch CancelledError in close_all(), use WeakKeyDictionary for
cancellation_reasons to prevent memory leak, guard StateManager
update_state/reset/load_checkpoint/time_travel after close().
P2: contextlib.suppress in __del__ for partial construction, re-cancel
pending tasks in cleanup_tasks_async, handle late tasks added during
await window, guard AcpEventQueue.publish() after close with _is_closed
flag and is_closed property, fix ASV TimeRegisterBatch crash.
Tests: 5 new Behave scenarios (T1-T4 + is_closed), log handler and
event loop cleanup in after_scenario (T5-T6).
Docs: async_safety.md updated for register-after-close and state
mutation guards.

ISSUES CLOSED: #321
2026-02-26 14:30:43 +00:00
khyari hamza 5d5d3fde2c fix(security): close async resources and leaks
Add AsyncResourceTracker (core/async_cleanup.py) providing a central
registry for async resources with timeout-bounded close_all(), async
context manager support, and a __del__ finalizer that logs leaked
resources by name.

Enhance LangGraphBridge with cleanup_tasks_async() that awaits
in-flight tasks with a deadline instead of fire-and-forget cancel().
Add cancellation_reasons dict to trace why tasks were cancelled.

Add StateManager.close() to properly release checkpoint file handles
and complete the RxPY BehaviorSubject. Add AcpEventQueue.close() to
dispose all subscriptions.

Includes 14 Behave scenarios (67 steps), Robot integration tests,
ASV benchmarks, and docs/reference/async_safety.md.

ISSUES CLOSED: #321
2026-02-26 14:30:43 +00:00
aditya 7ad9f2bf4a chore: update CHANGELOG for feat(skill): add agent skills loader
ISSUE CLOSED #160
2026-02-26 14:28:09 +00:00
hamza.khyari db58a3bb62 Merge pull request 'feat(decision): add decision persistence layer' (#131) from feature/m4-decision-persistence into master
Reviewed-on: cleveragents/cleveragents-core#131
Reviewed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-02-26 14:25:27 +00:00
khyari hamza 7f2b1c61fc fix(decision): rebase migration onto merged changeset head
After rebasing onto master, m4_001_decision_tables and
d0_002_merge_changeset_and_locks were both leaf heads.  Update
down_revision so the decision migration chains after the merge
migration, restoring a single Alembic head.

ISSUES CLOSED: #171
2026-02-26 13:40:07 +00:00
khyari hamza 27bef69ddd feat(decision): add decision persistence
Add decision persistence layer with DecisionRepository, DecisionModel,
and Alembic migration. Includes tree queries (BFS traversal via deque,
path-to-root), superseded lookup, ordered decision path retrieval,
concrete Decision type annotations (via TYPE_CHECKING), and comprehensive
test coverage (Behave BDD, Robot Framework, ASV benchmarks). Updated
database_schema.md, CHANGELOG.md, and CONTRIBUTORS.md.

ISSUES CLOSED: #171
2026-02-26 13:40:07 +00:00
aditya 595cfd172f Merge branch 'master' into feature/m3-mcp-adapter 2026-02-26 13:30:29 +00:00
aditya e05afdcd27 Merge pull request 'feature/m2-actor-yaml' (#432) from feature/m2-actor-yaml into master
Reviewed-on: cleveragents/cleveragents-core#432
Reviewed-by: Luis Mendes <luis.mendes@cleverthis.com>
2026-02-26 13:19:00 +00:00
aditya b25a886df8 feat(skill): add MCP refresh hooks
Implement SkillRegistry.refresh(name) and refresh_all() to recompute
flattened tool sets on demand. Wire MCPToolAdapter.dispatch_notification()
to MCPRefreshHook, which debounces rapid notifications/tools/list_changed
bursts into a single refresh_all() call (default 0.5 s window).

Add safeguard that skips tool-ref validation when no ToolRegistry is
configured, emitting a single WARNING with recovery steps. Introduce
immutable SkillRefreshResult (refreshed/failed/skipped counts) with
to_summary() and merge() for CLI and log output.

New files:
- src/cleveragents/skills/refresh.py        (SkillRefreshResult)
- src/cleveragents/mcp/refresh_hook.py      (MCPRefreshHook)
- features/skill_refresh.feature            (19 Behave scenarios)
- features/steps/skill_refresh_steps.py
- robot/skill_refresh.robot                 (10 Robot tests)
- robot/helper_skill_refresh.py
- benchmarks/skill_refresh_bench.py         (ASV benchmarks)
- docs/reference/skill_refresh.md

Modified:
- src/cleveragents/skills/registry.py       (refresh, refresh_all)
- src/cleveragents/mcp/adapter.py           (notification listener API)
- src/cleveragents/skills/__init__.py       (export SkillRefreshResult)
- src/cleveragents/mcp/__init__.py          (export MCPRefreshHook)
- CHANGELOG.md

ISSUES CLOSED #168
2026-02-26 12:29:49 +00:00
aditya c40ea014dc feat(cli): add skill tools and refresh commands
Implemented agents skill refresh command to recompute tool flattening and sync
MCP-backed skills. Enhanced skill list/show/tools outputs with capability
summary fields.

- agents skill refresh <name>|--all to recompute flattening
- Enhanced skill list/show/tools with capability summary and tool counts
- Added --format json/yaml schemas for refresh output
- CLI errors for nonexistent skills and MCP sync failures
- Behave tests (skill_cli.feature), Robot tests (skill_cli.robot)
- ASV benchmarks (skill_cli_bench.py) for CLI overhead baseline
- Updated docs/reference/skill_cli.md with refresh command examples
- Documented refresh side effects and caching behavior

ISSUES CLOSED: #167
2026-02-26 10:57:07 +00:00
aditya cb82fc51df feat(skill): add agent skills loader
Implemented AgentSkillSpec loader that parses SKILL.md frontmatter and
progressive disclosure sections (discover/activate/deactivate) into
structured SkillStep objects with stable 1-based ordering.

Mapped Agent Skills to AgentSkillToolDescriptor with namespaced naming
(namespace/short_name), source="agent_skill", read-only defaults, and
AgentSkillResourceSlot bindings for scripts/, references/, and assets/
directories. All resource slots are unconditionally read_only.

Added explicit validation for missing frontmatter fields (name,
description) and invalid namespace format with actionable error messages.

Added docs/reference/agent_skills.md covering folder layout, SKILL.md
parsing rules, progressive disclosure model, and tool mapping.

Added Behave scenarios covering valid/invalid SKILL.md parsing,
namespaced naming, step ordering, missing frontmatter errors, progressive
disclosure lifecycle, tool mapping, and resource binding slots.

Added Robot Framework integration tests using the deploy-to-staging
example skill folder (robot/agent_skills_loader.robot).

Added ASV benchmarks for parsing throughput, folder load, progressive
disclosure lifecycle, and resource listing
(benchmarks/agent_skills_loader_bench.py).

ISSUES CLOSED: #160
2026-02-26 09:10:35 +00:00
aditya 519e26fb02 Merge branch 'master' into feature/m3-mcp-adapter 2026-02-26 06:44:38 +00:00
aditya b8d7c4c893 Merge branch 'master' into feature/m2-actor-yaml 2026-02-26 06:21:39 +00:00
brent.edwards c53b880a5e Merge branch 'master' into develop-brent-5 2026-02-26 03:44:19 +00:00
freemo e3fcce413b feat(changeset): persist changesets and diff artifacts
Add SQLite persistence for ChangeSet entries and ToolInvocation records
via new changeset_repository module implementing the ChangeSetStore protocol.

- Alembic migration d0_001 creates changeset_entries and tool_invocations tables
- SqliteChangeSetStore, ChangeSetEntryRepository, ToolInvocationRepository
- PlanApplyService.cleanup_changeset() for cancel/failure cleanup
- Behave tests (17 scenarios), Robot tests (5 cases), ASV benchmarks
- Reference documentation in docs/reference/changeset.md

Closes #163
2026-02-26 02:47:14 +00:00
brent.edwards cf59f285fd Merge feature/m4-correction-subplan-smoke into develop-brent-5 2026-02-26 02:15:24 +00:00
brent.edwards a00c33c4c6 Merge test/m4-e2e-verification into develop-brent-5 2026-02-26 02:15:19 +00:00
brent.edwards 2e2ae3b9b8 Merge test/m3-e2e-verification into develop-brent-5 2026-02-26 02:15:14 +00:00
brent.edwards 3d3c8fda33 Merge feature/m4-decision-tests into develop-brent-5 2026-02-26 02:15:01 +00:00
brent.edwards b3f126b147 Merge feature/m3-decision-validation-smoke into develop-brent-5 2026-02-26 02:14:14 +00:00
brent.edwards 3c9a3efdf1 fix(test): correct mock targets, method names, ULIDs, and CLI args in M4 smoke suite
- Patch CorrectionService at its module path, not the local-import site
- Use request_correction/execute_correction/analyze_impact (real API)
- Replace invalid 27-char subplan_id values with valid 26-char ULIDs
- Add required --guidance flag to dry-run CLI invocation
- Fix feature file assertions to match actual CLI output

Resolves CI failures in unit_tests (job 4) and coverage (job 6) for
run 645 on PR #441.
2026-02-26 02:01:47 +00:00
brent.edwards 4f079c20ea fix(test): route M3 E2E subcommands through CLI rendering path
- decision-tree-view, decision-explain, and decision-tree-persistence
  now invoke 'plan status --format plain' via mocked lifecycle service
  so regressions in CLI rendering/serialization are caught
- plan-generates-decisions now asserts use_action was called by the CLI
  and verifies plan status renders the strategize phase after creation
- Updated robot test case documentation to reflect CLI integration
2026-02-26 01:26:02 +00:00
brent.edwards b99510d016 fix(test): derive decision type count from enum instead of hard-coding 11
Replace hard-coded '11 decision types' with dynamic len(DecisionType) in
the assertion and remove the literal from scenario names, step patterns,
docstrings, and docs so the tests stay correct when new DecisionType
values are added.
2026-02-26 01:19:28 +00:00
brent.edwards 93730067a2 fix(test): address review findings in M3 smoke tests
- Replace dead after_scenario() hook with context.add_cleanup() calls
  so patchers are properly stopped (Behave only runs hooks from
  environment.py)
- Fix invalid ULID constants: pad DECISION/CORRECTION to 26 chars,
  replace invalid 'I' with 'J' in INVARIANT_ULID
- Add temp file cleanup for NamedTemporaryFile(delete=False) via
  context.add_cleanup() in behave steps and try/finally in robot helper
- Remove decision-persistence doc sections from testing.md that belong
  in PR #438, not this PR
2026-02-26 01:13:16 +00:00
brent.edwards ef58883f7a fix(test): harden retry_patterns feature against flaky CI failures
The jitter-spread scenario used millisecond-bucketed wall-clock
timestamps to assert that retried operations did not cluster.  On busy
CI runners — especially when a preceding scenario's time.sleep patch
leaked through a late cleanup — tenacity's retry waits became no-ops
and all five operations landed in the same millisecond bucket, tripping
the max_in_bucket <= 3 assertion.

Three hardening changes:

1. Jitter test: switch from time.time() to time.monotonic_ns() and
   replace the fragile bucket assertion with a unique-timestamp count
   (>= 2 distinct readings among 5 sequential operations).
2. Timeout test: eagerly restore time.sleep in a try/finally block so
   subsequent scenarios never observe the patched no-op, regardless of
   behave's cleanup ordering.
3. Async circuit breaker: lower recovery_timeout from 0.2 s to 0.1 s
   (the sleep step already waits 0.2 s) to give a wider safety margin
   on slow CI machines.
2026-02-26 00:51:11 +00:00
freemo 3a2b134f3c test(coverage): add Behave scenarios for remaining under-tested modules
Added Behave BDD feature files and step definitions targeting coverage
gaps in six modules:

- container.py: exercise get_database_url env-var fallback, AI provider
  None path, cached container singleton, override_providers edge cases
  (lines 66-69, 125-130; branches at 51, 57, 82, 87, 256, 284-288)
- correction_service.py: exercise exception-handling paths in
  execute_revert and execute_append via monkeypatched analyze_impact
  and ULID failures (lines 254-262, 320-328)
- plan_lifecycle_service.py: exercise _persisted UoW commit paths,
  InvalidPhaseTransitionError custom message branch, non-reusable
  action archive, and error_details merge logic (branches at 100,
  216, 237, 327, 461, 570, 576, 607)
- plan.py (CLI): exercise spec-dict optional field branches,
  _print_lifecycle_plan conditional rendering, use_action argument
  parsing, auto-resolve paths, legacy wrappers, and validation
  error branches across 66 scenarios
- skill.py (CLI): exercise singleton cache, timestamp-absent show,
  no-tools MCP, add/remove/list/show format and error branches
  across 26 scenarios
- models.py (DB): exercise to_domain/from_domain None-field branches
  in SkillModel, SessionModel, ToolModel, LifecycleActionModel,
  LifecyclePlanModel, NamespacedProjectModel, and SessionMessageModel
  across 41 scenarios

All 302 features, 6503 scenarios, 28271 steps pass (nox -e unit_tests).

ISSUES CLOSED: #446
2026-02-25 19:38:43 -05:00
brent.edwards c80cda2590 Merge feature/m4-correction-subplan-smoke into develop-brent-5 2026-02-25 22:11:33 +00:00
brent.edwards a2b0611722 Merge branch 'test/m4-e2e-verification' into develop-brent-5 2026-02-25 22:10:46 +00:00
brent.edwards 49f097472a Merge branch 'test/m3-e2e-verification' into develop-brent-5 2026-02-25 22:10:42 +00:00
brent.edwards 5a212481e1 Merge branch 'feature/m4-decision-tests' into develop-brent-5 2026-02-25 22:10:38 +00:00
brent.edwards 22986aaaf9 fix(test): correct dry-run assertion in M3 decision validation smoke
The CLI plain format output does not include the literal text "Dry Run"
(that string only appears in the Rich panel title). Assert against
"risk_level" which is present in the dry-run impact output instead.
2026-02-25 22:09:26 +00:00
brent.edwards 55df1915f1 fix(test): correct patch targets and ULID validation in M4 smoke helper
- Patch CorrectionService at its definition site instead of the lazy
  import location in plan.py (same fix as M3 helper)
- Replace hardcoded fake subplan/correction IDs with real ULIDs
  generated via ulid.ULID() to satisfy Pydantic pattern validation
- Add missing --guidance flag to correction dry-run CLI invocation
- Fix subplan-status-sequential assertion to check for plan_id
  (subplan_count is not part of the status JSON output)
2026-02-25 22:06:45 +00:00
brent.edwards 2e53caaef1 fix(test): correct patch target for CorrectionService in M3 e2e helper
The CorrectionService import in plan.py is a lazy import inside the
correct() function body, so it does not exist as a module-level attribute.
Patch the class at its definition site instead:
  cleveragents.application.services.correction_service.CorrectionService

Fixes CI integration_tests failure for PR #439.
2026-02-25 22:00:39 +00:00
brent.edwards 917c2bc546 test(e2e): add M4 correction + subplan suites 2026-02-25 21:51:26 +00:00
brent.edwards cfc319ad27 test(e2e): verify M4 success criteria — subplans and parallel execution 2026-02-25 21:46:58 +00:00
brent.edwards ace7311de4 test(e2e): add M3 decision + validation suites 2026-02-25 21:26:19 +00:00
brent.edwards f4c4884d03 test(persistence): add decision persistence suites
Add comprehensive persistence test suites for the Decision domain model
covering serialization round-trips (model_dump/model_validate, JSON),
context-snapshot persistence, correction-chain reconstruction, and
decision-tree reconstruction from serialized data.

Deliverables:
- Behave: 21 scenarios in features/decision_persistence.feature
- Robot Framework: 7 integration tests in robot/decision_persistence.robot
- ASV benchmarks: 4 suites (17 benchmarks) in benchmarks/decision_persistence_bench.py
- Documentation: Updated docs/development/testing.md

ISSUES CLOSED: #180
2026-02-25 21:19:57 +00:00
brent.edwards aeb5cc5110 test(e2e): verify M3 success criteria — decision tree and correction
Robot Framework E2E test suite for M3 milestone verification covering:
- Plan execution generating decisions during Strategize phase
- Decision tree viewing with parent-child relationships and BFS traversal
- Decision explanation with full context snapshot verification
- Invariant add/list via CLI and InvariantService with scope filtering
- Dry-run correction via CorrectionService with impact analysis
- Live revert correction execution with decision re-creation
- Context snapshot round-trip serialisation assertions
- Decision tree persistence via model_dump/model_validate
- Correction revert re-execution from decision point
- Invariant enforcement during strategize with merge precedence

ISSUES CLOSED: #404
2026-02-25 21:15:29 +00:00
brent.edwards b437fb8fd4 Merge pull request 'test: consolidated Brent QA batch — issues #156, #169, #326, #402, #403' (#431) from develop-brent-4 into master
Reviewed-on: cleveragents/cleveragents-core#431
2026-02-25 20:46:18 +00:00
brent.edwards d055b59d7c Merge branch 'master' into develop-brent-4 2026-02-25 20:05:18 +00:00
brent.edwards 583ff60bf3 fix(test): lower jitter spread threshold to prevent flaky CI failure
The 'Test Concurrent Retries With Jitter' test asserted that 5 concurrent
retry timestamps spread across >10ms.  On busy CI runners thread scheduling
can compress wakeups into a narrower window, causing spurious failures.
Lowered the threshold from 10ms to 1ms — still validates that jitter produces
non-identical delays while tolerating CI scheduling variance.
2026-02-25 20:04:36 +00:00