- Format auto_debug.py per ruff to fix CI / lint failure
- Revert registry.py provider/model model-field change that conflicts with TDD test assertions from issue #10926 (models must use bare identifiers without provider prefix)
- Fix CHANGELOG entry: replace non-existent update_node()/set_active_node() with
actual method names (_analyze_error, _generate_fix, _validate_fix, _finalize)
and clarify LangGraph node contract reference (HAL9000 observation #1).
- Add inline comment explaining shallow-copy semantics in _analyze_error's
immutability pattern (HAL9000 observation #2): list is new but inner dicts
are shared refs — safe because messages are immutable-after-creation.
- Document return-asymmetry in _validate_fix docstring: both fix_validated and
attempted_fixes keys when invalid, only fix_validated when valid. This is
intentional LangGraph behavior (omitted keys are not reset) (HAL9000 obs #4).
Addresses review comments from peer review #8822 (HAL9000).
The feature file for auto-debug state mutation tests was missing required
TDD tags (@tdd_issue, @tdd_issue_10496). This caused CI / tdd_quality_gate
to fail the tag validation check. Added minimal tagging to pass CI while
keeping the fix PR's scenarios passing (no @tdd_expected_fail needed since
the underlying bug is being fixed).
The version, info, and diagnostics commands were incorrectly stated as being on the fast-path. Only --help and --version are eager exit options that skip subcommand module loading.
ISSUES CLOSED: #7592
Add a verified CLI showcase for the version, info, and diagnostics commands,
register in examples.json and update CHANGELOG/CONTRIBUTORS.
ISSUES CLOSED: #7592
Address reviewer blocking issues on PR #11003:
1. Remove unused `import os` and inner `MagicMock` re-import from the
gemini fallback step definitions (ruff F401).
2. Remove `@tdd_expected_fail` from the TDD feature now that the
registry fix makes the scenario pass; keep `@tdd_issue` /
`@tdd_issue_4750` as permanent regression markers.
3. Rewrite three feature step texts to use the env-var step defs that
already exist in `provider_registry_steps.py` instead of duplicating
them (drops the `env var` phrasing the original feature used and that
had no matching step def).
4. Add `"gemini"` to `FallbackSelector.DEFAULT_FALLBACK_ORDER` after
`"google"` so the actor-configured fallback chain mirrors the
registry-level fix.
5. Rename three of the new feature/step pairs to avoid ambiguous-step
collisions that crashed every behave-parallel worker at module-load
time (the root cause of the "8 features errored, 0 scenarios"
pattern):
- `the result should be ProviderType "GEMINI"` collided with
`cli_steps.py:138`'s `@then("the result should be {expected}")`;
renamed to `the gemini fallback default should be
ProviderType "GEMINI"`.
- `the result should be None` had the same collision; renamed to
`the clean gemini registry default should be None`.
- `@given("I have the ProviderRegistry class")` was duplicated in
`provider_registry_steps.py:186`; the duplicate is removed and the
existing definition is reused.
ISSUES CLOSED: #10906
The provider registry's FALLBACK_ORDER was missing ProviderType.GEMINI,
which meant Gemini-only configured installations could not select the
Gemini provider as default via the fallback chain.
This fix adds GEMINI right after GOOGLE in the priority order, consistent
with how it appears in DEFAULT_CAPABILITIES, DEFAULT_MODELS, and
PROVIDER_KEY_ATTRS - all of which already support Gemini.
Includes BDD regression coverage in features/fallback_gemini_provider.feature.
ISSUES CLOSED: #10906
Signed-off-by: HAL 9000 <hal9000@cleverthis.com>
- Replace MagicMock() LLM with FakeListLLM (a proper LangChain Runnable)
to avoid TypeError when PromptTemplate.__or__ evaluates the chain expression
- Use patch.object() context manager to mock _chain_with_retry cleanly
- Fix type annotations from lowercase any to typing.Any
- Separate validation response setup from chain mocking for cleaner test flow
ISSUES CLOSED: #10746
Fix duplicate step_impl function names in Behave test steps that caused
only the last-defined step to be registered with Behave, making all
scenarios fail with undefined step errors. Each step now has a unique
function name following the step_given/step_when/step_then convention.
Also fix the step parameter handling: Gherkin passes quoted string
parameters with their surrounding quotes included, so strip quotes from
the response and status parameters before comparison.
Remove the redundant if/else branch in the validation node step that
called the same code path in both branches.
Add CHANGELOG entry for the fix.
ISSUES CLOSED: #10746
Remove the len(all_code) > 10 fallback in the _validate method that
was overriding the LLM validation response. Previously, any code longer
than 10 characters would cause validation to automatically pass regardless
of the LLM's assessment, making the validation check ineffective.
The fix ensures validation status is determined solely by whether the LLM
response contains 'PASS', making the validation meaningful.
A regression test was added to verify that FAIL/REJECTED LLM responses
are properly handled even for long code blocks.
ISSUES CLOSED: #10746
Add ProviderType.GEMINI to both ProviderRegistry.FALL_BACK_ORDER and
FallbackSelector.DEFAULT_FALLBACK_ORDER, ensuring Gemini is included
in provider fallback chains for auto-discovery. Also remove the
@tdd_expected_fail tag from the TDD regression test since the bug
is now fixed.
ISSUES CLOSED: #10906
- Add _apply_output_dict() building the spec-required JSON envelope
- Update lifecycle_apply_plan to use _apply_output_dict for --format json
- Rewrite robot file to use Run Process + helper dispatch pattern
- Rewrite robot helper to use real LifecyclePlan domain objects
- Apply ruff format to plan_apply_json_envelope_steps.py
The `agents plan apply --format json` command was returning a raw
plan dictionary instead of the spec-required JSON envelope. This fix
introduces a dedicated `_apply_output_dict()` helper that wraps the
non-rich format output in the proper envelope structure with
`command`, `status`, `exit_code`, `data`, `timing`, and `messages`
fields.
The `data` field contains structured information about artifacts,
changes, project, applied_at, validation (test/lint/type_check),
sandbox_cleanup, and lifecycle metrics. Other commands (plan status,
plan cancel, plan use) remain unaffected — they continue using
`_plan_spec_dict`.
Tests: 16 Behave scenarios + 15 Robot Framework integration tests
added covering envelope structure, field presence, sandbox cleanup
state derivation from actual plan state, legacy fallback, cost
metadata, and command isolation.
ISSUES CLOSED: #9449
Add two BDD scenarios that mock os.walk and the time module so the
outer-loop and inner-file-loop timeout-exceeded branches in
detect_directory_languages() are deterministically exercised. Closes
the diff-coverage gap on src/cleveragents/lsp/discovery.py lines
250-257 (outer-loop timeout warning + break) and 284-291 (inner-loop
timeout warning + break) which the previous DoS protection scenarios
did not reach.
Refs: #7161
The @tdd_issue and @tdd_issue_7161 tags were placed inside the Feature
description body (indented after Feature:), where Behave treats them as
free-text, not tags. The parser fails at the plain-text description line
that follows ("Prevent resource exhaustion...") because it entered the
taggable_statement state after seeing the @-prefixed lines.
Moving both tags to before the Feature: line makes them proper
feature-level tags. All 9 scenarios inherit @tdd_issue via effective_tags,
satisfying the validate_tdd_tags() rule that every @tdd_issue_N scenario
must also carry @tdd_issue. All 9 scenarios now pass.
Refs: #7161
Resolved three blocking review items from pr-review-worker:
1. Added @tdd_issue tag at Feature level to fix unit_tests CI failure
(each scenario has @tdd_issue_7161 which requires @tdd_issue present)
2. Assigned milestone v3.6.0 to align with linked issue #7161
3. Applied ruff format to resolve lint/format violations in discovery.py
Added robust guards to detect_directory_languages() by introducing depth, file count, and timeout controls. Defaults and validations are implemented to prevent resource exhaustion during LSP discovery.
- Added max_depth parameter (default: 50) with validation to ensure a positive integer.
- Added max_files parameter (default: 10,000) with validation to ensure a positive integer.
- Added timeout parameter (default: 30.0 seconds) with validation to ensure a positive float.
- Pass followlinks=False to os.walk() to prevent symlink-based DoS via recursive loops.
- Implemented depth tracking in the traversal loop with early break when max_depth is exceeded.
- Implemented file count tracking with early break when max_files is exceeded.
- Implemented periodic timeout checks during traversal to enforce the overall time limit.
- Added warning logging when traversal is terminated early due to any limit.
- Updated the function docstring to document the new parameters and their defaults.
- Created comprehensive BDD tests in features/lsp_discovery_dos_protection.feature to validate the protections.
ISSUES CLOSED: #7161
The Semgrep patterns node is a YAML list (not dict), so the previous
implementation's .get() call on patterns would fail with AttributeError.
Fix: properly handle 'patterns' as a list of alternation groups, each
containing pattern-either -> patterns -> pattern-not entries. This
ensures the BDD assertion robustly finds bare raise pattern-nots in
the xml-no-suppressed-exception rule's nested structure.
Issues Closed: #9103
Document HAL 9000's contribution of the broad exception suppression
Semgrep guard (PR #9185, issue #9103) in CONTRIBUTORS.md per the
PR compliance checklist requirement.
Address blocking issues from PR review by HAL9001 (review #7080):
1. Add success_codes=[0, 1] to noxfile.py semgrep invocation so
the lint session runs in proper audit mode without failing CI on
the ~337 existing violations during phased rollout.
2. Strengthen BDD bare re-raise assertion: replace weak string search
for 'raise' with structured parsing of YAML pattern-not entries to
specifically verify bare raise patterns exist within the rule's
pattern-not configurations.
3. Add CHANGELOG.md entry under [Unreleased] documenting the Semgrep
guard implementation and its audit-mode migration strategy.
Issues Closed: #9103
Add 12 new Behave BDD scenarios to features/security_scan_hooks.feature
to automatically validate the Semgrep broad exception suppression rules
and their escape hatch behavior, as suggested by reviewer HAL9001.
New scenarios verify:
- python-no-suppressed-exception rule exists and targets src/
- python-no-suppress-exception rule exists and targets src/
- Both rules document the nosemgrep escape hatch in their messages
- Both rules document the error-propagation: allow annotation
- python-no-suppressed-exception has pattern-not for bare re-raise
- python-no-suppressed-exception has pattern-not for exception chaining
- Nox lint session integrates Semgrep and references .semgrep.yml
All 25 scenarios pass (13 original + 12 new).
ISSUES CLOSED: #9103
Fix broken escape hatch mechanism and address reviewer feedback:
- Replace non-functional comment-based pattern-not clauses with Semgrep's native # nosemgrep mechanism for the escape hatch. Semgrep strips comments from the AST so pattern-not clauses matching inline comments never fire; # nosemgrep is the only reliable per-line suppression mechanism.
- Require both # nosemgrep: <rule-id> AND # error-propagation: allow on the same line: the former is the actual suppression, the latter is the mandatory human-readable audit annotation.
- Add raise $EXC from $CAUSE pattern-not entries for both Exception and BaseException variants to prevent false positives on legitimate exception chaining (raise ServiceError from e).
- Switch nox -s lint Semgrep invocation to audit mode (no --error) for the phased rollout: the codebase has ~337 existing suppressions that must be triaged before enforcement mode is enabled. A comment in noxfile.py documents the migration path and references #9103.
- Update CONTRIBUTING.md examples and enforcement description to reflect the dual-comment requirement.
Fixed two critical issues with the Semgrep rules for broad exception suppression:
1. **Escape hatch mechanism**: Replaced the broken `# error-propagation: allow` comment-based escape hatch with Semgrep's native `# nosemgrep` comment support. Semgrep strips comments from the AST, so pattern-not clauses looking for inline comments never match. The native `# nosemgrep` comment is properly supported by Semgrep and provides a reliable override mechanism.
2. **Missing exception chaining pattern**: Added `raise $EXC from $CAUSE` pattern-not entries for both `Exception` and `BaseException` variants. This prevents false positives when legitimate exception chaining is used (e.g., `raise ServiceError("context") from e`), which is an allowed pattern per CONTRIBUTING.md.
Updated both `python-no-suppressed-exception` and `python-no-suppress-exception` rules with these fixes. The escape hatch now works reliably and exception chaining is properly recognized as an allowed pattern.
ISSUES CLOSED: #9103
Added two new Semgrep rules to enforce the CONTRIBUTING.md guideline against broad exception suppression:
- python-no-suppressed-exception: Detects except Exception/BaseException blocks without re-raising
- python-no-suppress-exception: Detects contextlib.suppress(Exception/BaseException) usage
Both rules support an escape hatch annotation '# error-propagation: allow' for documented recovery logic.
Integrated Semgrep into the nox lint session to run alongside Ruff checks.
Updated CONTRIBUTING.md to document the escape hatch policy and automated enforcement.
Pre-commit hook already configured to run these rules.
ISSUES CLOSED: #9103