Commit Graph

1526 Commits

Author SHA1 Message Date
Luis Mendes ab911dbdc4 fix(cli): write machine-readable formats directly to stdout bypassing Rich line-wrapping
The format_output() function returned a string that callers passed to
Rich console.print(), which wraps long lines at terminal width.  This
injected literal newline characters into JSON string values (e.g. in
definition_of_done fields), producing invalid JSON that downstream
parsers could not decode (JSONDecodeError: Invalid control character).

For machine-readable formats (json, yaml, plain), format_output() now
writes the rendered output directly to sys.stdout and returns an empty
string.  This preserves the exact serialization from json.dumps/
yaml.dump without Rich text processing artifacts.

Refs: #746
2026-03-17 09:53:57 +00:00
Luis Mendes 2acb957d83 fix(cli): replace in-memory automation-profile repository with database-backed persistence
The automation-profile CLI commands used an _InMemoryProfileRepository
(a Python dict) that lost all data between CLI process invocations.
Profiles created with "automation-profile add" were invisible to
subsequent "automation-profile show" or "list" calls because each CLI
command is a separate process with a fresh empty dict.

Changes:
- Replaced _InMemoryProfileRepository with the real
  AutomationProfileRepository from the infrastructure layer, wired
  via the DI container following the same pattern as tool.py and
  session.py.
- Added auto_commit support to AutomationProfileRepository (matching
  the existing SessionRepository pattern) so that CLI commands running
  outside a UnitOfWork commit each operation automatically.
- Added safety_json and guards_json Text columns to the
  automation_profiles table (Alembic migration m6_005) for full-fidelity
  round-trip of the AutomationGuard and SafetyProfile sub-models.
  Previously, guards and several safety fields (max_cost_per_plan,
  max_retries_per_step, etc.) were silently dropped on persistence.
- Updated _from_domain, _to_domain, and _update_row to serialize and
  deserialize the full guard and safety sub-models via JSON, with
  backward-compatible fallback to legacy scalar columns.

Refs: #746
2026-03-17 09:53:53 +00:00
brent.edwards c0658c2acf Merge pull request 'fix(test): remove eager tdd_test_helpers import from mocks __init__' (#985) from fix/benchmark-tdd-import into master
Reviewed-on: cleveragents/cleveragents-core#985
2026-03-16 23:29:51 +00:00
brent.edwards 288246d9b5 fix(test): remove eager tdd_test_helpers import from mocks __init__
The re-export of make_mock_scenario from features/mocks/__init__.py
caused ASV benchmark discovery to fail because tdd_test_helpers imports
behave.model.Status, which is unavailable in the ASV benchmark
virtualenv.  All callers already import via the full module path
(features.mocks.tdd_test_helpers), so the re-export was unnecessary.

ISSUES CLOSED: #628
2026-03-16 23:22:05 +00:00
brent.edwards c19c2b2e2c Merge pull request 'feat(testing): implement @tdd_expected_fail tag handling in Robot Framework' (#673) from feature/m5-robot-tdd-tags into master
Reviewed-on: cleveragents/cleveragents-core#673
Reviewed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Reviewed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-16 23:13:30 +00:00
brent.edwards c13a62a2f2 Merge branch 'master' into feature/m5-robot-tdd-tags 2026-03-16 23:06:19 +00:00
brent.edwards d0ca129d90 Merge branch 'master' into feature/m5-robot-tdd-tags 2026-03-16 23:05:43 +00:00
freemo 2688c85769 feat(extensibility): implement Custom Sandbox Strategy Registration via SandboxStrategy Protocol
Implement SandboxStrategyProtocol, a 9-method @runtime_checkable Protocol enabling
third-party sandbox strategy registration. Includes:

- SandboxStrategyProtocol with create/read/write/diff/commit/rollback/checkpoint/
  restore_checkpoint/cleanup methods
- SandboxRef (frozen dataclass) and DiffView/DiffEntry (Pydantic models)
- SandboxStrategyRegistry with config-driven registration, Protocol validation,
  thread safety, and clear/list/has operations
- BuiltInSandboxStrategyAdapter wrapping existing Sandbox implementations to conform
  to the new Protocol
- CustomStrategyConfig for YAML/dict-based strategy registration
- SandboxFactory integration with custom_registry parameter,
  has_custom_strategy() and get_custom_strategy_class()
- 25 Behave BDD scenarios (85 steps) covering protocol, registry, adapter, config,
  and factory integration
- 8 Robot Framework integration tests with real filesystem operations
- ASV benchmarks for registry and adapter operations
- Developer documentation

ISSUES CLOSED: #586
2026-03-16 22:50:27 +00:00
hurui200320 a5de448856 feat(testing): implement @tdd_expected_fail tag handling in Robot Framework
Implements the three-tag TDD bug-capture system in Robot Framework via a
Listener v3 module, paralleling the Behave implementation. Tests tagged
tdd_expected_fail that fail have their result inverted to PASS (bug still
exists); tests that unexpectedly pass are inverted to FAIL with guidance.

Addresses all 15 findings from code review (PR !673, reviewer hamza.khyari):

P2 fixes:
- Added idempotency guard (_processed_tests set) to prevent double-inversion
  when the listener is loaded twice in the same process.
- Rewrote normal-test-unaffected check to run alongside a tdd_expected_fail
  fixture in a single Robot invocation, proving the listener is loaded and
  selectively applies rather than being a tautological pass.

P3 fixes:
- Added output.xml existence guard with clear diagnostics in _run_fixture.
- Documented intentional use of data.tags (static definition) vs result.tags
  (runtime-modifiable) in end_test docstring.
- Added SKIP status test fixture and integration test case.
- Added message content assertion in cmd_expected_fail_inverted.
- Tightened substring assertions to match specific error text.
- Added tdd_expected_fail-alone fixture (both companions missing).
- Added close() hook to clear _validation_errors and _processed_tests.
- Simplified _run_fixture return type to tuple[str, str].
- Changed listener path resolution from CWD-relative to __file__-relative
  in noxfile.py (integration_tests, slow_integration_tests, e2e_tests).

P4 fixes:
- Added __all__ declaration to helper module.
- Changed module docstring from "mirroring" to "paralleling".
- Added comment documenting accepted XML parsing risk (self-generated XML).

Additional fixes:
- Increased M4 E2E plan-tree test timeout from 30s to 120s (pre-existing
  timeout failure unrelated to this feature).

Quality gates (post-rebase onto latest master):
- nox -s lint: PASS
- nox -s typecheck: PASS (0 errors)
- nox -s unit_tests: PASS (10,700 scenarios)
- nox -s integration_tests: PASS (1,505 tests)
- nox -s coverage_report: PASS (97.9% >= 97% threshold)
- nox -s benchmark: PASS
- nox -s docs: PASS
- nox -s build: PASS
- nox -s security_scan: PASS
- nox -s dead_code: PASS

ISSUES CLOSED: #628
2026-03-16 22:45:55 +00:00
freemo 05503712ae Docs: Daily update to timeline 2026-03-16 17:40:17 -04:00
hamza.khyari 028cf150b7 Merge pull request 'feat(acms): implement UKO Layer 3 Technology Vocabularies (uko-py, uko-ts, uko-rs, uko-java)' (#660) from feature/m6-uko-layer3-technology-vocabularies into master
Reviewed-on: cleveragents/cleveragents-core#660
Reviewed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-16 12:18:06 +00:00
hamza.khyari 89eaee008d feat(acms): implement UKO Layer 3 Technology Vocabularies (uko-py, uko-ts, uko-rs, uko-java)
Implement Layer 3 technology-specific UKO vocabulary extensions for Python,
TypeScript, Rust, and Java with language-specific classes, properties, and
DetailLevelMap insertions.

- 4 OWL/Turtle ontology files with language-specific semantic classes
- DetailLevelMap insertion logic with correct integer reassignment
- Provenance contract (5 required fields per spec)
- Full 4-layer chain resolution (Layer 3 -> Layer 2 -> Layer 1 -> Layer 0)
- Comprehensive Behave test suite (63 scenarios)

ISSUES CLOSED: #576
2026-03-16 12:11:08 +00:00
brent.edwards 3b6b1d2414 Merge pull request 'test(plan): TDD failing tests for checkpoint real rollback (bug #822)' (#929) from tdd/m6-checkpoint-real-rollback into master
Reviewed-on: cleveragents/cleveragents-core#929
Reviewed-by: Luis Mendes <luis.mendes@cleverthis.com>
2026-03-16 03:31:43 +00:00
brent.edwards 3119383529 Merge branch 'master' into tdd/m6-checkpoint-real-rollback 2026-03-16 03:15:10 +00:00
brent.edwards 3eecb79003 test(plan): TDD failing tests for checkpoint real rollback (bug #822)
TDD expected-fail tests proving bug #822 exists:
CheckpointService.rollback_to_checkpoint() returns a successful
RollbackResult but does not execute git reset --hard. Files modified
after the checkpoint remain unchanged after rollback.

Also fixes Robot Framework timeout robustness across the entire test
suite: all Run Process calls now use on_timeout=kill (prevents
SIGTERM-induced -15 exit codes under CI load) and timeouts increased
to 120s (prevents premature kills during heavy parallel execution).

ISSUES CLOSED: #839
2026-03-16 01:45:50 +00:00
brent.edwards 2d4b12df6a Merge pull request 'test(plan): TDD failing tests for subplan spawn orchestration (bug #823)' (#930) from tdd/m6-subplan-spawn-orchestration into master
Reviewed-on: cleveragents/cleveragents-core#930
2026-03-16 01:34:55 +00:00
brent.edwards b67dc63eda test(plan): TDD failing tests for subplan spawn orchestration (bug #823)
Write Behave scenario and Robot Framework test proving that
SubplanService.spawn() only creates metadata (SubplanStatus records
and SpawnMetadata) without creating real child Plan domain objects
or triggering lifecycle progression. Tests are tagged
@tdd_expected_fail so CI passes via result inversion.

ISSUES CLOSED: #838
2026-03-16 01:12:24 +00:00
freemo dfa05a6909 fix(cli): wire real LLM actors into plan executor for production execution
The `plan execute` CLI command only performed phase transitions
(Strategize → Execute) without ever invoking the `PlanExecutor` to
drive the strategize or execute actors.  `PlanExecutor.__init__`
unconditionally created `StrategizeStubActor()` and
`ExecuteStubActor()` which parse text locally and return empty
changesets — no real LLM call was made.

Added `_get_plan_executor()` helper that resolves `ProviderRegistry`
from the DI container and constructs `LLMStrategizeActor` /
`LLMExecuteActor` for real LLM invocations via LangChain.  Updated
`execute_plan` CLI command to detect plan phase/state and
automatically run the appropriate actor:

- Strategize/queued  → run strategize actor → transition to Execute
- Strategize/complete → phase transition only (backward compat)
- Execute/queued     → run execute actor → mark complete

New `llm_actors.py` module provides `LLMStrategizeActor` (task
decomposition into numbered steps) and `LLMExecuteActor` (code
generation with FILE: blocks).  Both resolve `provider/model` actor
names (e.g. `openai/gpt-4`) to live LangChain LLM instances.

`PlanExecutor.__init__` now accepts optional `strategize_actor` and
`execute_actor` parameters, falling back to stubs when None.
Existing mock-based BDD tests remain backward-compatible via duck-
typing fallback (MagicMock.phase is not a PlanPhase, so the legacy
`service.execute_plan()` path is taken).

Includes Behave BDD scenarios testing custom actor injection into
PlanExecutor.

ISSUES CLOSED: #960
2026-03-15 19:59:38 -04:00
freemo 2d423bdfcd fix(cli): add missing --format flag to action create command
The `action create` CLI command was the only action subcommand missing
the `--format`/`-f` parameter.  All other action subcommands (`list`,
`show`, `archive`) already accepted `--format` and routed through
`_print_action()`.  Running `action create --config action.yaml
--format plain` failed with a Typer unrecognized-option error.

Added the `fmt` parameter (with `--format`/`-f` aliases, defaulting
to `rich`) to the `create()` function signature and passed it through
to the existing `_print_action()` helper which already handles all
output formats.  Added Behave BDD scenarios for `--format plain` and
`--format json` to `action_cli_spec_alignment.feature`.

ISSUES CLOSED: #959
2026-03-15 19:33:11 -04:00
freemo 065171f21c test(e2e): E2E acceptance criteria for M2 (v3.1.0) — actor compiler and LLM integration
Add Robot Framework E2E test suite robot/e2e/m2_acceptance.robot exercising
M2 acceptance criteria with zero mocking. Test creates a temp git repo with
sample project files, registers a custom actor via CLI, sets up resource and
project, creates an action referencing the actor, and runs the full plan
lifecycle (use → execute strategize → execute → diff → apply). Validates
actor YAML compilation, skill registry, tool lifecycle, and LLM integration
through real CLI invocations with real provider API keys. Uses flexible
structural assertions and expected_rc=None for LLM-dependent commands.

ISSUES CLOSED: #742
2026-03-15 19:32:44 -04:00
freemo 5f07316641 fix: wire DI persistence and plan execute/apply for M1 lifecycle
Fixed 5 bugs preventing the M1 E2E acceptance test from passing:

1. _get_lifecycle_service() in action.py and plan.py bypassed the DI
   container, creating PlanLifecycleService without UnitOfWork. All
   plan/action data was in-memory only and lost between subprocess
   calls. Now uses container.plan_lifecycle_service() for DB persistence.

2. `plan execute` CLI only called service.execute_plan() (a pure state
   transition) without running PlanExecutor phase processing. Rewrote
   to detect the plan's current phase/state and dispatch synchronously:
   Strategize/queued → run_strategize(), Strategize/complete → transition
   + run_execute(), Execute/queued → run_execute().

3. `plan apply` CLI had no plan_id argument. Added optional positional
   plan_id with _lifecycle_apply_with_id() that drives the plan through
   Apply/queued → Apply/processing → Apply/applied.

4. Preflight guardrail in start_strategize() built action_registry from
   the in-memory _actions dict only. Added get_action(plan.action_name)
   call to load the action from DB into cache before the guardrail check.

5. Robot Framework Create File syntax used continuation lines producing
   9 arguments instead of 1. Fixed to use Catenate SEPARATOR=\n then
   pass single variable to Create File. Also fixed --branch main to
   --branch master (git init default).

update mocks for execute_plan CLI changes across unit and integration tests

The new execute_plan() command calls _get_plan_executor() and
service.get_plan(plan_id) for phase/state detection. Existing tests
only mocked _get_lifecycle_service, so MagicMock defaults caused
phase/state comparisons to fail.

Changes across 14 files:
- Patch _get_plan_executor in all test setups that invoke the CLI
  execute command (Behave step files + Robot helper scripts)
- Set service.get_plan.return_value to real Plan objects with correct
  phase/state so the execute_plan dispatch logic works
- Fix error-path tests to use STRATEGIZE/COMPLETE plans so the error
  side_effects are actually reached
- Fix "Multiple plans eligible" → "Multiple plans ready" message text
  to match existing test expectations

increase Robot Framework subprocess timeouts for CI resource contention

Three integration tests were timing out in CI due to resource contention
when pabot runs multiple test suites in parallel. All three pass locally
and the timeouts were simply too tight for constrained CI environments.

- tdd_session_create_di.robot: 30s → 90s (DI container init + DB setup)
- database_integration.robot: 60s → 120s (Run Python Script keyword)
- m3_e2e_verification.robot: 60s → 120s (correction-live-revert spawns
  3 sequential CLI subprocesses with full container initialization)

ISSUES CLOSED: #789
2026-03-15 20:50:02 +00:00
freemo cb3b7aab44 test(e2e): E2E acceptance criteria for M1 (v3.0.0) — minimal plan execution flow
Added Robot Framework E2E test suite for M1 milestone acceptance criteria.
Tests the complete plan lifecycle (action create → resource add → project
create → plan use → plan execute strategize → plan execute → plan diff →
plan apply) with real LLM API keys and no mocking.

Key implementation details:
- Uses openai/gpt-4o-mini as strategy/execution actor (cost-effective)
- Simple definition_of_done: "Create a file called HELLO.md"
- Creates isolated temp git repo via Create Temp Git Repo keyword
- Extracts plan ID via ULID regex from plain-text output
- Uses expected_rc=None for LLM-dependent steps (execute, diff, apply)
  to handle non-deterministic LLM behavior gracefully
- Flexible structural assertions: checks rc, output presence, git log
- Skips gracefully when no LLM API keys (ANTHROPIC/OPENAI) are set
- Tagged [E2E] so it runs only in nox -s e2e_tests session

ISSUES CLOSED: #741
2026-03-15 20:50:02 +00:00
freemo 21a8e672a3 Docs: Contributing now enforces 97% coverage 2026-03-14 21:20:43 -04:00
freemo ce722ed0ea ops(ci): configure LLM API keys in Forgejo CI for integration test execution
Updated CI pipeline to inject ANTHROPIC_API_KEY and OPENAI_API_KEY
secrets as environment variables during Robot Framework integration
test execution. Added CI setup documentation.

ISSUES CLOSED: #701
2026-03-14 22:34:18 +00:00
freemo af6340e732 Docs: Daily update to timeline 2026-03-14 18:26:20 -04:00
freemo 67291b4614 Docs: Updated chat room 2026-03-14 18:26:16 -04:00
freemo 09f1d621bf Docs: Daily update to timeline 2026-03-14 18:26:12 -04:00
freemo ec450e9085 fix(test): fix tolerant exit code and missing RC check in resource CLI test
- Replace `rc == 0 or rc == 1` with strict `rc == 0` in resource type
  list test so failures are no longer silently accepted
- Capture and assert the return code of the Suite Setup database schema
  creation to fail fast if the setup itself is broken

apply strict RC checks to resource_cli.robot

- Capture return value of Run Process in Suite Setup and assert rc==0
- Replace tolerant RC check (rc==0 or rc==1) with strict Should Be Equal
  As Integers check for resource type list test case

broaden exception handling in resource CLI commands

Add catch-all `except Exception` handler after each `except
CleverAgentsError` block in all 14 resource CLI command handlers.
This ensures unexpected exceptions (e.g. sqlalchemy.exc.OperationalError)
are caught and displayed gracefully instead of producing raw tracebacks.

re-raise typer.Abort/Exit in broad exception handlers

The `except Exception` handlers added in the previous commit
inadvertently caught typer.Abort and typer.Exit, which are
subclasses of Exception (via click.exceptions).  This turned
successful CLI exits into aborts and double-handled already-caught
errors, breaking integration tests that rely on normal typer exit
behaviour.

Add an isinstance guard to re-raise typer.Abort and typer.Exit
before the catch-all handler runs.

Fixes #896
2026-03-14 15:47:03 -04:00
freemo 447328a92d fix(test): remove retry masking and output filtering in database integration test 2026-03-14 03:56:18 +00:00
freemo 9ef8502570 fix(database): reset session factory after engine disposal in init_database 2026-03-14 03:56:18 +00:00
freemo 8c9d9c8c33 fix(providers): add missing module docstring to providers package 2026-03-14 03:45:18 +00:00
freemo a69af285a8 fix(test): remove retry masking and output filtering in database integration test
- Remove silent retry logic in Run Python Script that masked intermittent
  failures by retrying on empty stdout + non-zero RC
- Change output filter from 'in' to 'startswith' so only lines beginning
  with log prefixes are filtered, not lines containing them mid-string
- Remove [error from the filter list so error lines are never silently
  discarded from test output

Fixes #898
2026-03-14 03:45:18 +00:00
freemo 00c46c12fd fix(test): convert soft warnings to hard failures in architecture test
Replace Run Keyword And Return Status soft checks with direct assertions
in three test cases:

- Docstring check now uses Should Contain directly instead of logging
  WARN, so missing docstrings cause a hard test failure.
- Settings file (config/settings.py) existence is now a hard File Should
  Exist assertion instead of a conditional that silently skips all
  checks when the file is absent.
- Exceptions file (core/exceptions.py) existence is now a hard File
  Should Exist assertion instead of a conditional that silently skips
  the exception hierarchy checks when the file is absent.
2026-03-14 03:45:18 +00:00
freemo 9148590542 fix(providers): add missing module docstring to providers package 2026-03-14 03:33:37 +00:00
freemo 64e606099c fix(test): convert soft warnings to hard failures in architecture test
Replace Run Keyword And Return Status soft checks with direct assertions
in three test cases:

- Docstring check now uses Should Contain directly instead of logging
  WARN, so missing docstrings cause a hard test failure.
- Settings file (config/settings.py) existence is now a hard File Should
  Exist assertion instead of a conditional that silently skips all
  checks when the file is absent.
- Exceptions file (core/exceptions.py) existence is now a hard File
  Should Exist assertion instead of a conditional that silently skips
  the exception hierarchy checks when the file is absent.
2026-03-14 03:33:37 +00:00
freemo 586ea4557f fix(test): add return code checks to intermediate commands in core CLI test
Add rc == 0 assertions to ~11 intermediate Run Process calls in core_cli_commands.robot that were used as setup steps without any return code verification. If any setup command (init, tell, build, context add, plan new) fails silently, subsequent test assertions could pass for wrong reasons. All setup commands now capture their result and assert rc == 0.
2026-03-14 01:35:49 +00:00
hamza.khyari 14884ba15e Merge pull request 'refactor(a2a): update test files for ACP to A2A rename' (#737) from refactor/m7-acp-to-a2a-tests into master
Reviewed-on: cleveragents/cleveragents-core#737
Reviewed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-14 01:35:33 +00:00
hamza.khyari 4133c46aff refactor(a2a): update test files for ACP to A2A rename
Replace two remaining 'ACP' references with 'A2A' in vulture_whitelist.py
comments (lines 633, 957) missed by the source rename in PR #705.

Closes #689
2026-03-14 01:28:27 +00:00
freemo c169cb201d fix(test): remove skip guard and soft assertions from scientific paper E2E test
- Remove Require OpenAI Key skip guard that silently skipped the suite
- Replace Run Keyword And Return Status soft RC check with direct assertion
- Convert conditional LaTeX presence check to hard assertions
- Convert conditional latex_source context field check to hard assertion
- Remove dead stderr checks (stderr redirected to stdout via stderr=STDOUT)
2026-03-14 00:50:29 +00:00
freemo 77a7813f0e fix(test): tighten diagnostics check exit code assertion in CLI core test
Replace the tolerant "rc == 0 or rc == 1" assertion with a strict
"rc == 0" check for the diagnostics --check command. In a clean test
environment, diagnostics should complete without finding errors, and the
previous assertion could not distinguish a legitimate diagnostic failure
from a command crash.
2026-03-14 00:37:34 +00:00
freemo eb2c2362bd fix(test): remove skip guard from scientific paper basic test
Remove the Require OpenAI Key keyword and its call from Suite Setup.
Tests now fail with a real error when OPENAI_API_KEY is absent,
providing honest signal instead of silently skipping.
2026-03-13 23:55:27 +00:00
hamza.khyari 232ef965f5 Merge pull request 'feat(acms): implement UKO Layer 2 Paradigm Vocabularies (uko-oo, uko-func, uko-proc)' (#657) from feature/m6-uko-layer2-paradigm-vocabularies into master
Reviewed-on: cleveragents/cleveragents-core#657
Reviewed-by: Aditya Chhabra <aditya.chhabra@cleverthis.com>
2026-03-13 18:28:11 +00:00
hamza.khyari 3c014a9565 feat(acms): implement UKO Layer 2 Paradigm Vocabularies (uko-oo, uko-func, uko-proc) 2026-03-13 18:21:50 +00:00
hurui200320 317d015260 test(e2e): validate M4 acceptance criteria for v3.3.0 milestone closure
Strengthen M4 E2E CLI acceptance tests and address all review findings
from the self-review on PR #681 (3 blocking, 7 non-blocking issues).

Blocking fixes:
- Remove tautological domain assertions from cli_plan_execute() that
  verified values the test itself constructed via _mock_parent_plan and
  could never fail.  Replace with a comment documenting that subplan
  info cannot be verified from CLI output alone.
- Fix unguarded positional arg access in plan_diff() that would raise
  IndexError if the production CLI passes plan_id as a keyword argument.
  Now uses kwargs-with-positional-fallback pattern.
- Split the 1074-line helper_m4_e2e_verification.py into four focused
  modules under the CONTRIBUTING.md 500-line limit:
    helper_m4_e2e_common.py (237 lines) — constants, helpers, factories
    helper_m4_e2e_domain.py (495 lines) — domain model tests
    helper_m4_e2e_cli.py    (426 lines) — CLI integration tests
    helper_m4_e2e_verification.py (81 lines) — thin dispatcher

Non-blocking improvements:
- Add ProjectLink isinstance type guard before iterating project_links.
- Wrap all assert_called_once*() calls in try/except with _fail()
  pattern to produce standardised FAIL: diagnostics instead of raw
  AssertionError.
- Make project_links extraction symmetric with action_name (kwargs +
  positional fallback at index 1).
- Replace broad "execute" substring match with word-boundary regex
  r"\bexecute\b" to avoid false positives from incidental substrings.
- Extract _make_subplan_status() factory, _assert_exit_code() and
  _assert_mock_called_once*() wrappers to eliminate DRY violations
  (SubplanStatus construction repeated 3x, exit-code checks 4x).
- Replace non-deterministic datetime.now() calls with frozen constant
  _FROZEN_NOW = datetime(2026, 3, 1, 12, 0, 0) for deterministic
  fixtures.
- Rename generic _DECISION_ULID_N constants to descriptive names
  (_DECISION_PROMPT_DEF, _DECISION_STRATEGY, _DECISION_PARALLEL_SPAWN,
  _DECISION_SPAWN_API, _DECISION_SPAWN_UI).

Quality gates:
- lint: PASS
- format: PASS (1404 files unchanged)
- typecheck: PASS (0 errors)
- unit_tests: 10,431 scenarios, 0 failures
- integration_tests: 1,452 tests, 0 failures
- coverage_report: PASS (98%, threshold 97%)
- security_scan: PASS
- dead_code: PASS
- docs: PASS
- build: PASS

ISSUES CLOSED: #495
2026-03-13 14:03:37 +08:00
hurui200320 eb770643c2 test(e2e): validate M5 acceptance criteria for v3.4.0 milestone closure
Add four CLI-based integration test cases to the M5 E2E verification suite
that exercise the exact commands from the v3.4.0 milestone description via
real subprocess calls to `python -m cleveragents`.

CLI test cases:
- CLI Project Create Large Project: `agents project create local/large-project`
- CLI Resource Add Git Checkout: `agents resource add git-checkout ...`
- CLI Project Link Resource: `agents project link-resource ...`
- CLI Project Show Displays Linked Resource: `agents project show ...`

Each test creates an isolated temp directory with its own CLEVERAGENTS_HOME,
initialises a workspace via `agents init`, runs the target CLI command as a
subprocess with `on_timeout=kill`, asserts zero exit code and verifies
expected output, then tears down the temp directory.

Bug fix: ProjectResourceLinkRepository.create_link() and remove_link() only
called session.flush() without session.commit(), causing linked resource data
to be silently lost between sessions. Added session.commit() to both methods,
plus finally: session.close() to match the session-factory lifecycle pattern
used by all other mutating repository methods. Added session.refresh() and
session.expunge() before return in create_link() so the returned ORM instance
is fully loaded and usable in detached state after session close.

Regression guard: Added two cross-session persistence Behave scenarios
(project_repository.feature) that open a new session from the same engine
after create_link/remove_link and verify the operation was durably committed.

Test improvements from review feedback (rounds 1 and 2):
- Per-test CLEVERAGENTS_HOME isolation via env: override on all Run Process
  calls to prevent shared state between tests.
- Stronger ULID-based assertions: CLI tests capture the resource_id ULID from
  resource show output and verify the exact ID in project show output.
- Regex-based branch assertion (branch.*main) instead of generic string match.
- Test 4 differentiated from Test 3 by verifying resource show independently
  after linking and asserting the specific resource ULID.
- Documentation noting context tier and ACMS criteria are validated at the
  Python API level via helper_m5_e2e_verification.py.
- Updated ProjectResourceLinkRepository class docstring documenting commit
  and close behaviour of mutating methods.
- CHANGELOG entry for both test additions and production bug fix.
- Redundant Library imports removed, --format plain on project list, comments
  explaining fake repo directories, standardised Run Process line style.

Context/ACMS CLI coverage is intentionally not added because the CLI does not
yet expose dedicated context/ACMS inspection commands. These criteria are
validated at the Python API level via helper_m5_e2e_verification.py.

ISSUES CLOSED: #496
2026-03-13 13:32:52 +08:00
CoreRasurae 3e3e9b4b5d feat(observability): wire AuditService.record() into domain services via EventBus auto-dispatch
Implements AuditEventSubscriber that subscribes to all 9 security-relevant
EventType members and persists redacted audit entries via AuditService.record().

Key components:
- AuditEventSubscriber: bridges EventBus and AuditService (SEC7)
- SECURITY_EVENT_MAP: maps EventType enum to audit type strings
- Redaction via redact_dict() on event details before persistence
- Graceful error handling: failures logged, never propagated

Post-review fixes applied:
- BUG-1: Remove dead correlation_id null-check guard (DomainEvent.correlation_id
  is always non-None via ULID default_factory)
- SEC-2: Redact exception messages in warning logs via redact_value() to prevent
  potential leakage of sensitive internal state (e.g. DB connection strings)
- PERF-3: Pre-generate unique DomainEvent instances in ASV benchmark setup to
  avoid skew from reusing a single frozen object
- Wire event_bus from the DI container into CorrectionService (plan.py),
  ConfigService (config.py, skill.py x2, server.py), and
  PersistentSessionService (session.py) at their CLI construction sites.

Closes #581
2026-03-12 23:32:48 +00:00
brent.edwards b90f2cccdc Merge pull request 'fix(test): convert M1-M6 E2E suites to real subprocess CLI invocations (closes #658)' (#784) from bugfix/m6-e2e-mock-only-coverage into master
Reviewed-on: cleveragents/cleveragents-core#784
2026-03-12 22:13:47 +00:00
brent.edwards 717550c59e Merge branch 'master' into bugfix/m6-e2e-mock-only-coverage 2026-03-12 22:03:28 +00:00
brent.edwards 9141676329 Merge pull request 'test(e2e): TDD failing tests for E2E mock-only coverage (bug #658)' (#738) from tdd/m6-e2e-mock-only-coverage into master
Reviewed-on: cleveragents/cleveragents-core#738
2026-03-12 22:02:02 +00:00
brent.edwards 94d953246d fix(test): correct mock wiring in plan_correct_tree_wiring Robot helper
Replace container.resolve.return_value with container.decision_service.return_value
to match actual CLI code (plan.py uses container.decision_service()). This was the
residual pattern from before the DI migration in this same PR.

Fixes CI: Robot.Plan Correct Tree Wiring (2 of 3 tests failing with exit code 1)
2026-03-12 21:53:38 +00:00