- Rewrite TUI session export/import step definitions to use constructor-
based dependency injection (container_factory) instead of
unittest.mock.patch context managers that fail across fork() boundaries
in the parallel test runner.
- Add container_factory parameter to TuiCommandRouter dataclass so tests
can inject a mock container that survives multiprocessing.fork().
- Add use_step_matcher('re') to a2a_jsonrpc_wire_format_steps.py so
regex-based step patterns are matched correctly (fixes 30 errored
scenarios with 56 undefined steps).
- Add plural 'rows' variant to database_handler_crud_steps.py row-count
step matcher (fixes 1 errored scenario).
ISSUES CLOSED: #2597
Fix all failing CI quality gates (lint, unit_tests, format) without
suppressing any quality enforcement.
Root causes and fixes:
1. Format: features/steps/plan_namespaced_name_tdd_steps.py had trailing
whitespace; fixed by running ruff format.
2. Unit tests - A2A JSON-RPC 2.0 migration (commit 9c6d6915) renamed
A2aRequest fields (operation→method, request_id→id, a2a_version→jsonrpc)
and A2aResponse fields (status+data→result, request_id→id) but did not
update all step files and feature files:
- a2a_jsonrpc_wire_format_steps.py: added use_step_matcher('re') and
reset to 'parse' at end to prevent parallel test interference
- a2a_facade_wiring_steps.py: updated operation= to method=, .status/.data
to .result
- a2a_facade_steps.py: updated request_id→id, a2a_version→jsonrpc,
A2aResponse(request_id=..., status=...) to new API
- m6_facade_steps.py: updated all old API usage
- devcontainer_cleanup_steps.py: updated A2aRequest(operation=...)
- plan_prompt_command_steps.py: updated A2aRequest(operation=...)
- wf03_plan_prompt_confidence_steps.py: updated A2aRequest(operation=...)
- consolidated_misc.feature: updated old A2aRequest/A2aResponse scenarios
3. Unit tests - Session CLI output changed (commit 0d5d9cf0 and others):
- 'Session Created' → 'Session created' (lowercase)
- 'Session Details' → 'Session Summary'
- 'Sessions (N total)' → 'Sessions'
- session list JSON: top-level 'total' → nested 'summary.total'
- Fixed in: session_cli.feature, session_cli_coverage_boost.feature,
session_cli_uncovered_branches.feature, session_list_error.feature,
tdd_session_create_persist_steps.py
4. Unit tests - Plan list output changed (commit 1a07a891):
- 'V3 Lifecycle Plans' → 'Plans'
- 'Lifecycle Plans' → 'Plans'
- Name column removed (restored in source)
- Invariants column removed (restored in source)
- Project truncation removed (restored in source)
- Fixed in: plan_cli_cancel_revert_coverage.feature,
plan_lifecycle_cli_coverage.feature, plan_cli_coverage_boost_steps.py,
plan.py (source code restored)
5. Unit tests - Plan apply command now requires ULID (commit 300a5d6d):
- plan_cli_coverage_r3.feature: updated 'PLAN-001' to valid ULID
- plan_cli_coverage_r3_steps.py: added --yes flag, added new step for
no-eligible-plans path
6. Unit tests - Various source code bugs:
- ThoughtBlock: converted from @dataclass to Pydantic BaseModel
(architecture test requires all dataclasses to use Pydantic)
- session.py: added DatabaseError handling to export, import, tell commands
- database.py: fixed rollback_to() to reuse checkpoint connection for writes
- database.py: added _get_checkpoint_conn() helper
- check-tls-cert.py: fixed SSLCertVerificationError.reason AttributeError
7. Unit tests - Test step bugs:
- error_recovery_coverage_boost_steps.py: fixed invalid ULID _PLAN_ID
- session_service_coverage_steps.py: fixed 'sha256:' prefix bug in checksum
- database_models_new_coverage_steps.py: added 'name' field to session mock
- async_audit_recording_steps.py: fixed Settings(audit_async=False) via env var
- coverage_threshold_config_steps.py: added --coverage-min pattern support
- m5_acms_smoke_steps.py: updated usage hint text
- actor_cli_yaml_steps.py: updated 'Removed actor' → 'Actor removed'
- aimodelscredentials_steps.py: set context.imported_class in import step
- domain_base_model.feature: added missing 'When I examine model_config' step
- tui_first_run_steps.py: fixed module reload to restore cleveragents.tui.*
modules after test (prevented patch interference in subsequent tests)
- tui_first_run_steps.py: added set_search('') step for empty string
- resource_handler_base_coverage_r3_steps.py: use _MinimalHandler instead
of DatabaseResourceHandler for NotImplementedError tests
- resource_handler_crud.feature: updated to test new DatabaseHandler behavior
- resource_handler_sandbox.feature: updated to test new DatabaseHandler behavior
- tdd_json_decode_crash_persistence.feature: fixed @tdd_bug → @tdd_issue tags
8. Parallel test interference:
- All step files using use_step_matcher('re') now reset to 'parse' at end
to prevent global matcher state leaking to subsequent step files
Add missing `finally: if self._auto_commit: session.close()` blocks to all four public session-creating methods in AutomationProfileRepository: get_by_name(), list_all(), upsert(), and delete(). Closes#987
All 8 nox-running CI jobs in .forgejo/workflows/ci.yml now capture
stdout+stderr to build/nox-<job>-output.log via `2>&1 | tee` and upload
the log as a named Forgejo artifact (if: always(), retention-days: 30).
Artifact names follow the pattern ci-logs-<job>:
ci-logs-lint, ci-logs-typecheck, ci-logs-security, ci-logs-quality,
ci-logs-unit-tests, ci-logs-integration-tests, ci-logs-e2e-tests,
ci-logs-coverage
Seven agent definitions updated with a CI Log Artifacts section:
ca-pr-checker.md: artifact table + curl download instructions; Step 2
now downloads the relevant artifact before dispatching fix subagents.
ca-lint-fixer.md, ca-typecheck-fixer.md, ca-unit-test-runner.md,
ca-integration-test-runner.md, ca-coverage-checker.md,
ca-pr-self-reviewer.md: each receives a section explaining which
artifact corresponds to its domain and how to use it.
Design notes:
- tee (not redirect) preserves output in CI job logs AND captures to file
- if: always() ensures artifacts are available even when the job fails
- Multi-session jobs (lint, security) use tee -a to append to one file
- Existing coverage-reports artifact preserved alongside ci-logs-coverage
ISSUES CLOSED: #2750
The Forgejo blocks/dependencies REST API requires the IssueMeta schema
with owner, repo, and index fields — not the undocumented dependency_id
field that was previously used. All 10 curl examples across 6 agent
definitions were using {"dependency_id": N} which returns a 404
IsErrRepoNotExist error. Updated to the correct format:
{"owner": "<owner>", "repo": "<repo>", "index": N}
Files updated:
- ca-new-issue-creator.md (2 occurrences)
- ca-pr-api-creator.md (1 occurrence)
- ca-state-reconciler.md (1 occurrence)
- ca-project-owner.md (1 occurrence)
- ca-backlog-groomer.md (2 occurrences)
- ca-epic-planner.md (3 occurrences)
ISSUES CLOSED: #2750
Add the missing --namespace/-n option to lifecycle_list_plans() in
plan.py, mirroring the existing implementation in list_actions() in
action.py. The service layer already supported namespace filtering;
only the CLI layer was missing the option.
Changes:
- Add namespace parameter to lifecycle_list_plans() with --namespace/-n
option flags and 'Filter plans by namespace' help text
- Pass namespace through to service.list_plans(namespace=namespace, ...)
- Update TUI Filters panel to display 'Namespace: <value>' when provided
- Add usage examples to command docstring
- Add 4 Behave unit test scenarios covering --namespace/-n option
- Add 2 Robot Framework integration tests verifying namespace filtering
ISSUES CLOSED: #2165
Add DomainBaseModel section to docs/api/core.md documenting the shared Pydantic base class from PR #2014 (issue #1941), and add CHANGELOG entry for the CI template DB extension from PR #2399 (issue #2334).
ISSUES CLOSED: #1941
Co-authored-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Co-committed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
MCPToolAdapter.invoke() was reading error messages from result.get('error',
'unknown error'), but the MCP 1.4.0 protocol returns errors in the content
field as a list of content items with type and text keys. This caused every
error from a real MCP 1.4.0-compliant server to be silently replaced with
the string 'unknown error'.
Changes:
- src/cleveragents/mcp/adapter.py: extract error_text from content[0].text
with safe guards (isinstance check, length check) and fallback to
'unknown error' when content is absent or empty
- features/mocks/mock_mcp_transport.py: return MCP 1.4.0-compliant error
responses using content list format instead of the non-standard error key
- features/tdd_mcp_error_content_key.feature: Behave scenario verifying
correct error extraction from MCP 1.4.0 content arrays (written as TDD
issue-capture, @tdd_expected_fail removed after fix applied)
- features/steps/tdd_mcp_error_content_key_steps.py: step definitions for
the new scenario including _MCP14ErrorTransport mock subclass
All 51 MCP adapter scenarios pass. Typecheck: 0 errors. Lint: clean.
ISSUES CLOSED: #2158
Add missing `finally: if self._auto_commit: session.close()` blocks to
all four public session-creating methods in `AutomationProfileRepository`:
`get_by_name()`, `list_all()`, `upsert()`, and `delete()`. Without
these blocks, sessions were never closed when the repository operated in
auto_commit mode, causing a slow session leak that could exhaust the
connection pool over time.
The fix mirrors the pattern already used by `SessionRepository`, which
correctly closes its session in a `finally` block for every public method.
Removed the `@tdd_expected_fail` tag from the TDD test
(`tdd_automation_profile_session_leak.feature`) so the six scenarios
now run as normal regression tests (four original plus two new scenarios
for `get_by_name` and `list_all`).
ISSUES CLOSED: #987
Enhance the system watchdog with OpenCode Server API session introspection
to read actual supervisor conversations, tool calls, and todo lists.
Upgrade Audit 6 (Zombie Detection) to use message-based analysis instead
of only checking Forgejo activity — reads last 5 messages from each
supervisor session to detect sleep-only patterns, error loops, and
identical repeated tool calls.
Add Audit 11 (Quick Session Spot-Check) running every 5-minute cycle:
scans the 3 most recently active sessions for critical policy violations
including force_merge usage, direct pushes to master, and type:ignore
suppressions in written code.
Add Audit 12 (Deep Session Introspection) running every 30 minutes:
full analysis of all 16 supervisor sessions reading last 10 messages
and todo lists. Detects misbehavior patterns, progress stalls via todo
list analysis, conversation health metrics (error rates, sleep ratios),
context exhaustion signals, and cross-agent conflicts (multiple agents
touching the same PR or issue).
Update action dispatch to handle new finding types: force_merge_detected,
direct_push_to_master, stuck_supervisor, looping_supervisor, high_error_rate,
context_exhaustion, and cross_agent_pr_conflict.
Add ca-system-watchdog (16th supervisor) for continuous system health
monitoring with quality gate auditing, zombie detection, ticket state
reconciliation, and priority enforcement. Add ca-quality-enforcer and
ca-state-reconciler as one-off fix agents dispatched by the watchdog.
Critical fix: remove all force_merge: true usage from ca-pr-self-reviewer
which was bypassing branch protection and allowing PRs to merge with
failing CI. Replace with strict CI-gating merge logic that respects
branch protection rules per CONTRIBUTING.md.
Update product-builder to launch 16 supervisors, strengthen anti-return
language with explicit context hygiene, add tracking ticket lifecycle
management (one open at a time, closed on completion).
Update ca-project-bootstrapper with strict branch protection config
requiring status-check CI context, 2 approvals, and dismiss stale reviews.
Fix label set to match CONTRIBUTING.md exactly.
Update issue-implementor with priority gate enforcing lowest-milestone-first
and critical-bugs-first ordering. Update ca-backlog-groomer with closed
issue state reconciliation, PAT for REST API dependency operations, and
health signaling. Update ca-spec-updater with proactive full-scan mode.
Add health signaling and context self-management to 7 continuous
supervisors to prevent zombie sessions from context exhaustion.
Strengthen state label transitions in ca-pr-self-reviewer, ca-pr-api-creator,
ca-issue-state-updater, and ca-backlog-groomer to ensure closed issues
always have correct terminal state labels.
Add Forgejo PAT and REST API curl templates for dependency link creation
to ca-backlog-groomer and ca-project-owner since the MCP does not support
dependency manipulation.
Add reference documentation for three new TUI features:
- docs/reference/tui_shell_safety.md: Full reference for the shell danger
detection subsystem (DangerousPatternDetector, ShellDangerLevel,
DangerousPattern, DangerousCommandWarning, DEFAULT_PATTERNS registry).
Covers all built-in patterns across CRITICAL/HIGH/MEDIUM/LOW levels,
usage examples, and custom pattern extension.
- docs/reference/tui_permission_question.md: Full reference for the inline
PermissionQuestionWidget (issue #997). Documents InlinePermissionQuestion,
PermissionRequestType, PermissionDecision, render_permission_question(),
PermissionDecisionEvent, and PermissionQuestionWidget with key bindings
and usage examples.
- docs/reference/tui.md: Extended with First-Run Experience section
(ActorSelectionOverlay, first_run helpers), Inline Permission Questions
section, shell danger detection note in Shell Mode, updated module table,
and links to new reference pages.
Added critical warning block and step-by-step checklist to product-builder.md
to ensure the agent always follows the correct workflow:
1. Launch 15 supervisors via curl to http://localhost:4096/session/:id/prompt_async
2. Monitor them with bash sleep loop (60 seconds between checks)
3. Re-launch any that exit
Key changes:
- ⚠️ Critical execution model warning at top (what to do / what NOT to do)
- 📊 Execution flow diagram showing all phases
- ✅ Step-by-step Phase C checklist (C.1: Pre-flight, C.2: Launch, C.3: Monitor)
- 🔒 Clearer permission blocks with explicit bans on implementation agents
- 📝 Comments explaining why supervisors use curl not Task tool
This prevents the product-builder from trying to implement issues directly,
which is the supervisors' job. Product-builder is a process supervisor (like
systemd), not a worker.
This TDD test captures the buggy behavior where `NamespacedName.validate_namespace()`
and `validate_name()` accept names starting with digits, violating the spec requirement
that namespace and name components must start with a letter (consistent with
`_BARE_NAME_RE` in project.py).
Three failing scenarios demonstrate the bug:
1. parse() accepting namespace starting with digit ("123abc/my-action")
2. constructor accepting name starting with digit (local/"123-action")
3. constructor accepting namespace starting with digit ("999org"/valid-name)
Tagged with @tdd_expected_fail per Bug Fix Workflow.
Implements #2145
Blocks #2147
Both slow_integration_tests and e2e_tests sessions require a database
(via setup_workspace() in helper scripts) but were not using the
pre-migrated template DB optimization already present in unit_tests,
integration_tests, and coverage_report.
Changes:
- slow_integration_tests: add _create_template_db() call, set
CLEVERAGENTS_TEMPLATE_DB env var, upgrade from robot to pabot for
parallel execution, add NO_COLOR/PYTHONPATH/PATH/compileall setup,
add --include slow / --exclude discovery/code_blocks/wip/E2E/tdd_fixture
tag filters, and update docstring.
- e2e_tests: add _create_template_db() call and set
CLEVERAGENTS_TEMPLATE_DB env var. The existing setup_workspace()
in helper_e2e_common.py already checks this env var and copies the
template instead of running 25+ Alembic migrations.
No changes to test helper files are required since setup_workspace()
already implements the fast-path copy logic when CLEVERAGENTS_TEMPLATE_DB
is set.
ISSUES CLOSED: #2334
Agent evolver identified a critical systematic pattern:
- Pattern: The backlog groomer was closing PRs as 'duplicates' of their
linked tracking issues. A PR containing 'Closes #N' was being treated
as a duplicate of issue #N, when it is actually the implementation
delivery vehicle for that issue.
- Evidence: At least 12 PRs were incorrectly closed (#1219, #1236, #1247,
#1269, #1267, #953, #1198, #1220, #1237, #1238, #1246, #1248) — all
with the same 'Duplicate Detected' comment pattern from groomer-1.
- Fix: Added explicit instructions to skip PRs during duplicate detection,
added a guard in the analysis loop pseudocode, and added a rule in the
Important Rules section.
This change requires human approval before taking effect.
ISSUES CLOSED: #2180
Add PermissionQuestionWidget API documentation to docs/api/tui.md including
method table, key bindings, PermissionDecisionEvent dataclass, and
render_permission_question() helper reference. Add corresponding CHANGELOG
entry under [Unreleased] Added section.
Refs: #997
Implement inline permission question widget for quick allow/reject
decisions within the conversation stream with file diff context.
ISSUES CLOSED: #997
Align Unicode box-drawing blocks and related tables in specification.md,
ADR-044/045/046, and reference pages for consistent MkDocs rendering.
ISSUES CLOSED: #1171
Consolidate duplicate Added/Fixed headings in [Unreleased] section into single canonical sections per Keep a Changelog format. Add new entries for DomainBaseModel (#1941) and TDD bug-capture test (#1094).
Co-authored-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
Co-committed-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
Add a new Behave TDD regression scenario that persists corrupt automation-profile JSON and verifies repository reads do not leak raw JSONDecodeError. The scenario is tagged with @tdd_bug, @tdd_bug_989, and @tdd_expected_fail so it currently inverts the intentional assertion failure and will require tag removal when bug #989 is fixed.\n\nAlso stabilize an unrelated integration fixture in robot/resource_dag.robot by sharing a single SQLAlchemy session in inline scripts; this removes nondeterministic visibility of flushed resource-type rows and keeps required nox integration quality gates deterministic for this branch.\n\nISSUES CLOSED: #1094
Agent evolver identified a systematic pattern:
- Pattern: PR stale/conflict cascade
- Evidence: 11+ PRs were approved but closed without merge due to
conflicts. PRs #1248, #1247, #1237, #1236, #1220, #1219, #1238,
#1246, #1269 were all bulk-closed as stale. Reviewer notes on
#1248, #1220, #1219, #1252 explicitly mention 'merge blocked by
conflicts'. With 16 parallel workers, master moves fast and branches
created minutes earlier are already behind by the time PRs are created.
- Fix: Add a rebase-onto-latest-master step (Phase 3, Step 3.0) in
ca-issue-worker before committing and creating the PR. This ensures
the branch is current when the PR is opened, dramatically reducing
the chance of merge conflicts when the reviewer processes it.
This change requires human approval before taking effect.
Agent evolver identified a systematic pattern:
- Pattern: UAT tester filing bugs for features already being implemented
- Evidence: 25+ UAT bugs filed for TUI MainScreen features (#1329-#1355)
that already had open implementation PRs (#1219, #1236, #1237, #1238,
#1246, #1247, #1248, etc.). The tester reported 'missing sidebar',
'missing tab bar', 'missing escape navigation' etc. while PRs
implementing these exact features were open and under review.
- Fix: Add step 4 to duplicate avoidance requiring the tester to check
for open PRs before filing 'missing feature' bugs.
This change requires human approval before taking effect.
- Add missing 'nox -s format -- --check' step (parity with ci.yml)
- Add NOX_DEFAULT_VENV_BACKEND: uv to global env and each nox step
- Fix quality gates script invocation (was using invalid nox session '3.13')
- Fix report artifact paths to match actual nox session output locations
(build/coverage.json and build/bandit-report.json instead of build/reports/)
- Add mkdir for build/reports before writing quality-trend.json
ISSUES CLOSED: #1537
BREAKING CHANGE: Supervisors can no longer use Task tool to launch workers
Major refactor of the permission model for product-builder and all 15
continuous supervisors to enforce strict separation: supervisors MUST use
curl/prompt_async via bash to launch workers, and CANNOT use the Task tool.
Key Changes:
1. Product-Builder Permissions (product-builder.md):
- Removed ALL Task permissions for supervisors (previously had 17)
- Kept Task permissions ONLY for 7 one-shot agents:
ca-project-bootstrapper, ca-ref-reader, ca-issue-finder,
ca-session-persister, ca-product-verifier, ca-milestone-reviewer,
ca-final-reporter
- Restricted bash to: echo, curl, sleep, jq only
- Removed Phase B (Architecture) and Phase C.1 (Planning)
- Updated to launch 15 supervisors (up from 13)
2. New Continuous Supervisors:
- ca-architect: Converted from one-shot to continuous supervisor
Monitors for spec needs, new milestones, ambiguities
- ca-epic-planner: Converted from one-shot to continuous supervisor
Monitors for milestones without issues, incomplete epics
3. All 15 Supervisors - Standardized Permissions:
- Removed ALL Task permissions for launching workers
- Workers MUST be launched via curl to OpenCode Server prompt_async API
- Added 'jq *' for JSON parsing (replacing python3)
- Restricted bash to specific commands only (deny all, allow specific)
- Git commands restricted to specific operations (clone*, fetch*, etc.)
- Directory operations (cd, mkdir, rm -rf) only where needed
4. Supervisor-Specific Updates:
- issue-implementor: Removed ca-issue-worker task permission
- ca-continuous-pr-reviewer: Added git + directory ops, removed worker tasks
- ca-uat-tester: Added read-only file/git commands, removed self-dispatch
- ca-bug-hunter: Restricted git to read-only, removed self-dispatch
- ca-test-infra-improver: Added read-only commands, removed self-dispatch
- ca-human-liaison: Removed ca-epic-planner/ca-architect task permissions
- ca-agent-evolver: Added git + directory operations
- ca-architecture-guard: Added read-only + git clone operations
- ca-spec-updater: Added git + directory operations
- ca-backlog-groomer: Removed ca-epic-planner task permission
- ca-docs-writer: Added git + directory operations
- ca-timeline-updater: Added git + directory operations
- ca-project-owner: Minimal permissions (curl, jq, sleep only)
Impact:
- Proper separation of concerns: supervisors orchestrate, workers execute
- No possibility of supervisors blocking on Task tool calls
- True fire-and-forget worker launching via prompt_async
- Consistent permission model across all 15 supervisors
- Maximum parallelism with proper isolation
Architecture now enforces: Product-builder → 15 supervisors → N workers
All launched via curl/prompt_async, NO Task tool for supervisors.
Introduce DomainBaseModel in src/cleveragents/domain/models/base.py that
defines the single shared model_config (str_strip_whitespace, validate_assignment,
arbitrary_types_allowed=False, populate_by_name, use_enum_values) previously
duplicated verbatim across five domain model files.
Update 14 classes across five files to inherit from DomainBaseModel instead
of pydantic.BaseModel directly, removing all inline model_config duplication:
- aimodelscredentials/ai_models_credentials.py (ModelProviderOption)
- aimodelserrors/ai_models_errors.py (ModelError, FallbackResult)
- aimodelsproviders/ai_models_providers.py (ModelProviderExtraAuthVars,
ModelProviderConfigSchema)
- auth/auth.py (AuthHeader, TrialPlansExceededError, TrialMessagesExceededError,
BillingError, ApiError, ClientAccount, ClientAuth)
- planconfig/plan_config.py (PlanConfig, ConfigSetting)
Pure structural refactor — no behavioral changes. Models with different
configurations (acms, aimodels_custom, etc.) are left untouched.
Add BDD feature (22 scenarios) and Robot integration tests (8 test cases)
verifying inheritance, config correctness, and no-duplication invariants.
ISSUES CLOSED: #1941
Centralize E2E initialization in common suite setup so DB-dependent CLI commands no longer rely on per-suite or per-test init workarounds. This also sanitizes suite-home names to prevent invalid path-derived initialization failures in isolated Robot runs.
ISSUES CLOSED: #1023