Skip to content

auto-recover: orphaned worker branch for #2321 - #2324

Closed
superdav42 wants to merge 2 commits into
mainfrom
feature/auto-20260724-125342-gh2321
Closed

superdav42 wants to merge 2 commits into
mainfrom
feature/auto-20260724-125342-gh2321

Conversation

@superdav42

@superdav42 superdav42 commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Orphan recovery PR — worker pushed this branch but exited before opening a PR.

Branch feature/auto-20260724-125342-gh2321 was pushed by headless worker session issue-2321 which released as worker_branch_orphan. This PR was auto-created by the orphan-recovery path (GH#20819) so the change can land via the normal review and merge pipeline.

Resolves #2321


aidevops.sh v3.32.180 automated scan.

Summary by CodeRabbit

  • New Features

    • Added managed customer-agent profiles with lifecycle management, readiness status, versioning, and protected configuration.
    • Added structured handoff responses and trusted request context for customer-agent conversations.
    • Added profile-specific runtime cleanup and improved request processing reliability.
  • Bug Fixes

    • Explicitly empty public or anonymous ability and collection allowlists now correctly deny access instead of falling back to defaults.
    • Improved safety controls prevent customer requests from widening configured capabilities.
  • Database

    • Added storage and uniqueness support for managed customer-agent profiles.

@superdav42 superdav42 added status:in-review Non-draft PR ready for review/merge origin:worker-takeover Worker took over from interactive session labels Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@superdav42, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a4bdbd42-37a0-4255-8493-10beda3304ab

📥 Commits

Reviewing files that changed from the base of the PR and between 89c9bd3 and 9d3dea2.

📒 Files selected for processing (2)
  • includes/Services/CustomerAgentRuntimeService.php
  • tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php
📝 Walkthrough

Walkthrough

Adds versioned managed customer-agent profiles with ownership controls, schema persistence, constrained prompt composition, explicit anonymous deny-all policies, locked runtime execution, trusted request context, and structured handoff responses.

Changes

Managed customer-agent runtime

Layer / File(s) Summary
Managed profile persistence and ownership
includes/Core/Database.php, includes/Models/DTO/AgentRow.php, includes/Models/Agent.php, tests/SdAiAgent/Core/DatabaseSchemaTest.php, tests/SdAiAgent/Models/AgentTest.php
Managed profile fields, nullable unique keys, DTO decoding, ownership-aware updates/deletion, managed-profile serialization, and lifecycle persistence tests are added.
Customer prompt and anonymous policy enforcement
includes/Core/CustomerAgentPromptComposer.php, includes/Core/AgentLoop.php, includes/Abilities/KnowledgeAbilities.php, includes/Tools/ToolDiscovery.php, includes/REST/SessionController.php, tests/SdAiAgent/Core/*, tests/SdAiAgent/Abilities/*, tests/SdAiAgent/Tools/*, tests/SdAiAgent/REST/PublicChatControllerTest.php
Customer prompts now use sanitized support instructions, collections, and request context; explicit empty allowlists remain active deny-all policies across knowledge, tools, and public chat.
Managed profile lifecycle and runtime contract
includes/Contracts/CustomerAgentRuntimeInterface.php, includes/Services/CustomerAgentRuntimeService.php, includes/Models/CustomerAgentRuntimeRepository.php, tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php
The runtime contract and service add profile provisioning, status, disable/remove operations, managed-profile precedence, advisory locking, tombstones, transactional purging, and reconciliation behavior.
Locked execution and structured responses
includes/Services/CustomerAgentRuntimeService.php, tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php
Queued request context and profile snapshots are constrained during execution, while normalized replies persist separately from validated structured handoff data.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Consumer
  participant CustomerAgentRuntimeService
  participant AgentLoop
  participant ResponseNormalizer
  Consumer->>CustomerAgentRuntimeService: enqueue_turn(message, request_context)
  CustomerAgentRuntimeService->>CustomerAgentRuntimeService: persist constrained profile snapshot
  CustomerAgentRuntimeService->>AgentLoop: execute customer-agent turn
  AgentLoop-->>CustomerAgentRuntimeService: model response
  CustomerAgentRuntimeService->>ResponseNormalizer: normalize reply and handoff
  ResponseNormalizer-->>Consumer: structured response
Loading

Possibly related PRs

Suggested labels: enhancement

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is related to the PR, but it emphasizes branch recovery rather than the managed customer-profile changes.
Linked Issues check ✅ Passed The changes implement managed profiles, prompt composition, policy gating, and lifecycle/service updates required by #2321.
Out of Scope Changes check ✅ Passed The anonymous/public-chat gating and test updates align with the customer-profile and backward-compatibility scope.
Docstring Coverage ✅ Passed Docstring coverage is 94.32% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auto-20260724-125342-gh2321

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
includes/REST/SessionController.php (1)

1546-1572: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Removing the empty-abilities fallback makes a prompt/allowlist mismatch reachable.

This change correctly lets an admin configure an explicit deny-all public_chat_allowed_abilities (previously it was silently forced back to knowledge-search). But build_public_chat_system_instruction() unconditionally tells the model "Your only public tool is knowledge-search" regardless of the resolved list. With an empty allowlist now honored end-to-end, the model is instructed to call a tool that ToolDiscovery's deny-all gate will reject every time, producing confusing behavior instead of a clean deny-all experience.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@includes/REST/SessionController.php` around lines 1546 - 1572, The public
chat prompt must reflect an explicitly empty abilities allowlist instead of
always advertising knowledge-search. Update
build_public_chat_system_instruction() to use the resolved abilities from
get_public_chat_settings(), producing a deny-all instruction when the list is
empty and only describing allowed tools when present; preserve the existing
allowlist enforcement.
includes/Core/Database.php (1)

820-849: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Log and continue when managed_profile_key uniqueness cannot be enforced.

ensure_managed_profile_key_unique_index() returns false when non-unique duplicate profile keys exist, but install() returns before update_option( self::DB_VERSION_OPTION, self::DB_VERSION, true ). Since the idempotency check only skips when the stored version equals 19.8.0, later admin_init activation calls still run the full multi-table dbDelta() before exiting again, without leaving the admin informed why the install is failing or skipped. Log a clear schema-repair message and continue recording the DB version so future requests don’t repeatedly perform the migration work.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@includes/Core/Database.php` around lines 820 - 849, The install flow around
ensure_managed_profile_key_unique_index() should log a clear schema-repair
message when uniqueness cannot be enforced, then continue rather than returning
early. Ensure update_option( self::DB_VERSION_OPTION, self::DB_VERSION, true )
still executes so subsequent requests skip the repeated migration work, while
preserving the existing behavior when index enforcement succeeds.
🧹 Nitpick comments (7)
tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php (4)

425-431: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Two of the five forbidden keys aren't exercised.

apply_consumer_policy_narrowing() denies system_instruction, system_prompt, client_abilities, attachments, and tool_calls, but this table omits system_instruction and tool_calls — one array entry each in the existing loop.

Asserting the exact error code per case rather than just the forbidden_ prefix would also stop a mis-mapped rejection from passing silently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php` around lines
425 - 431, Update the forbidden-context cases in CustomerAgentRuntimeServiceTest
to include entries for system_instruction and tool_calls, matching the keys
denied by apply_consumer_policy_narrowing(). Strengthen the loop assertions to
verify each case’s exact expected forbidden error code rather than only checking
the forbidden_ prefix.

59-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Clean up tombstones for every tracked profile key, not just self::INTEGRATION.

Line 59 hardcodes the service's private tombstone naming (REMOVED_PROFILE_OPTION_PREFIX plus hash('sha256', 'integration|' . $key)) for one constant. It covers today's tests, but any future test that calls remove_profile() on a different key leaks a tombstone, and because resolve_integration() checks is_removed_profile() first, the leak surfaces as a confusing profile_removed (410) in an unrelated test.

Since $managed_profile_keys is already tracked, folding the tombstone delete into that loop makes cleanup self-maintaining.

♻️ Derive cleanup from the tracked keys
-		delete_option( 'sd_ai_agent_customer_agent_removed_profile_' . hash( 'sha256', 'integration|' . self::INTEGRATION ) );
-		foreach ( $this->managed_profile_keys as $profile_key ) {
+		foreach ( array_unique( array_merge( $this->managed_profile_keys, array( self::INTEGRATION ) ) ) as $profile_key ) {
+			delete_option( 'sd_ai_agent_customer_agent_removed_profile_' . hash( 'sha256', 'integration|' . $profile_key ) );
 			Agent::delete_managed_customer_profile( $profile_key );
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php` around lines 59
- 63, Update the teardown cleanup around managed_profile_keys to delete each
tracked profile’s tombstone within the existing loop, deriving the option name
with the service’s established tombstone prefix and hash format; remove the
hardcoded self::INTEGRATION deletion, then retain managed profile deletion and
reset the tracking array.

470-479: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Only the happy path of handoff validation is covered.

This pins the valid-intent round trip, but normalise_handoff()'s rejection rules are untested: an intent outside the four-value allowlist, a missing/empty reason, and a non-array handoff must all yield no handoff key in the DTO. A plain non-JSON reply (the documented backward-compatible path) is also unasserted.

Those are the branches that keep unvalidated model output out of the consumer contract, so they're worth pinning.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php` around lines
470 - 479, Extend the handoff validation tests around inspect_job and
normalise_handoff to cover an intent outside the four-value allowlist, missing
or empty reason, and non-array handoff; assert each DTO omits the handoff key.
Also add a plain non-JSON reply case and assert it remains supported without a
handoff entry, while preserving the existing valid-intent assertions.

206-220: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use keys that normalize to the same slug prefix.

managed-slug-a_b and managed-slug-a-b already produce distinct sanitize_title() prefixes because underscores are preserved in WordPress title sanitization, so the hash suffix is not the factor making this test pass. Use two keys that collapse to the same sanitize_title() output so the test actually guards collision resistance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php` around lines
206 - 220, Update the test around ensure_profile and
Agent::get_by_managed_profile_key to use two managed profile keys whose
sanitize_title() results are identical, such as variants differing only by
characters WordPress removes or normalizes. Keep the existing assertions
verifying both profiles are created, retrieved, and receive different agent
slugs.
includes/Services/CustomerAgentRuntimeService.php (3)

1371-1378: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

drift has two incompatible shapes across the managed and legacy paths.

The managed branch returns drift with safety_envelope_version and operator_resources_missing (Lines 371-374); this legacy branch returns only legacy_registration. Since profile_status() is an integration-facing contract typed loosely as array<string,mixed>, a consumer written against the managed shape hits undefined indexes on a legacy profile.

Emitting the full key set from both branches (with legacy_registration as an additional flag) keeps the response shape stable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@includes/Services/CustomerAgentRuntimeService.php` around lines 1371 - 1378,
The legacy response construction in CustomerAgentRuntimeService must emit the
same drift keys as the managed branch. Update the drift array in
profile_status() to include safety_envelope_version and
operator_resources_missing with the corresponding legacy-path values, while
retaining legacy_registration as an additional flag.

346-357: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

N+1 collection lookups run on every customer request, including job polling.

profile_status() is reached from resolve_integration() (Line 1049), so enqueue_turn, create_or_recover_conversation, inspect_job, cancel_job, close_conversation, and process_job each issue one KnowledgeDatabase::get_collection_by_slug() query per approved collection — and get_collection_by_slug() is an uncached direct $wpdb->get_row (includes/Knowledge/KnowledgeDatabase.php lines 175-193). Consumers poll inspect_job in a loop, so this multiplies.

Consider a single batched lookup for the availability probe, and/or restricting the availability probe to the write paths (ensure_profile, profile_status) rather than every read.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@includes/Services/CustomerAgentRuntimeService.php` around lines 346 - 357,
Replace the per-collection KnowledgeDatabase::get_collection_by_slug() calls in
profile_status() with a single batched availability lookup, or limit this
availability validation to the write paths ensure_profile() and profile_status()
so read and job-polling flows avoid repeated queries. Preserve the existing
customer_collections_not_approved and collections_unavailable reason behavior.

1255-1281: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

abilities is validated then discarded, and collections is uncapped.

Two gaps in the spec contract:

  • Lines 1265-1281 validate $spec['abilities'] against SAFE_ABILITIES, but the normalized spec never carries it and provisioning always writes self::SAFE_ABILITIES (Line 207). A consumer passing 'abilities' => array() is told nothing and silently gets knowledge-search. Either honour the narrowing or reject the key outright, so the validation isn't misleading.
  • Line 1256 accepts an unbounded collections list. Since profile_status() probes each approved slug individually, a large list turns every customer request into a proportionally large query burst. A modest cap here would bound that.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@includes/Services/CustomerAgentRuntimeService.php` around lines 1255 - 1281,
Update the customer profile normalization flow around $profile_version,
$collections, and $spec['abilities'] so validated abilities are either preserved
and used by provisioning instead of always writing self::SAFE_ABILITIES, or the
abilities key is rejected rather than ignored. Add a finite maximum for the
sanitized collections list and return the existing invalid-spec error when it
exceeds that limit, keeping valid lists unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@includes/Services/CustomerAgentRuntimeService.php`:
- Around line 1049-1055: Remove readiness enforcement from resolve_integration()
so read and cancellation paths such as find_owned_job(), inspect_job(), and
cancel_job() can resolve existing integrations despite profile drift. Keep
validation limited to resolving a valid, non-removed integration, and apply
profile_status readiness checks only when accepting new work in enqueue_turn()
or create_or_recover_conversation().
- Around line 875-885: Remove the integration-wide lock from the normal enqueue
and job-processing paths around acquire_integration_lock, process_job_locked,
and reschedule_locked_job, since idempotency and claim_queued_job already
provide their required coordination. Retain exclusive locking only around
lifecycle-mutation methods such as ensure_profile, disable_profile, and
remove_profile; if a lock remains necessary in these paths, use a 0–1 second
timeout so live requests fail fast rather than waiting behind another customer’s
provider turn.
- Around line 1727-1734: Update the JSON handling in CustomerAgentRuntimeService
so any decoded array lacking a usable string display_text, including JSON arrays
or alternate-key payloads, replaces the raw reply with the established generic
customer-safe fallback message. Preserve the existing display_text extraction
and handoff normalization when display_text is valid.
- Around line 1163-1185: The acquire_integration_lock method currently relies on
MySQL-specific GET_LOCK semantics that are not valid on SQLite or other
supported backends. Replace this advisory-lock implementation with the project’s
backend-agnostic lifecycle guard, or explicitly enforce and document MySQL-only
support if non-MySQL databases are unsupported, while preserving the busy
WP_Error behavior and lock-release contract.
- Around line 1318-1320: Remove the duplicate `@phpstan-param` annotation for
$approved_collections in the PHPDoc block, keeping one declaration with the
existing list<string> type.

In `@tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php`:
- Around line 529-545: Fix the managed_profile_spec() fixture so profiles are
ready during tests by either seeding an active support-docs knowledge collection
in set_up() or overriding collections to an empty list in the affected tests.
Ensure ensure_profile() succeeds and enqueue_turn() can run before
remove_profile() validates owned runtime records.

---

Outside diff comments:
In `@includes/Core/Database.php`:
- Around line 820-849: The install flow around
ensure_managed_profile_key_unique_index() should log a clear schema-repair
message when uniqueness cannot be enforced, then continue rather than returning
early. Ensure update_option( self::DB_VERSION_OPTION, self::DB_VERSION, true )
still executes so subsequent requests skip the repeated migration work, while
preserving the existing behavior when index enforcement succeeds.

In `@includes/REST/SessionController.php`:
- Around line 1546-1572: The public chat prompt must reflect an explicitly empty
abilities allowlist instead of always advertising knowledge-search. Update
build_public_chat_system_instruction() to use the resolved abilities from
get_public_chat_settings(), producing a deny-all instruction when the list is
empty and only describing allowed tools when present; preserve the existing
allowlist enforcement.

---

Nitpick comments:
In `@includes/Services/CustomerAgentRuntimeService.php`:
- Around line 1371-1378: The legacy response construction in
CustomerAgentRuntimeService must emit the same drift keys as the managed branch.
Update the drift array in profile_status() to include safety_envelope_version
and operator_resources_missing with the corresponding legacy-path values, while
retaining legacy_registration as an additional flag.
- Around line 346-357: Replace the per-collection
KnowledgeDatabase::get_collection_by_slug() calls in profile_status() with a
single batched availability lookup, or limit this availability validation to the
write paths ensure_profile() and profile_status() so read and job-polling flows
avoid repeated queries. Preserve the existing customer_collections_not_approved
and collections_unavailable reason behavior.
- Around line 1255-1281: Update the customer profile normalization flow around
$profile_version, $collections, and $spec['abilities'] so validated abilities
are either preserved and used by provisioning instead of always writing
self::SAFE_ABILITIES, or the abilities key is rejected rather than ignored. Add
a finite maximum for the sanitized collections list and return the existing
invalid-spec error when it exceeds that limit, keeping valid lists unchanged.

In `@tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php`:
- Around line 425-431: Update the forbidden-context cases in
CustomerAgentRuntimeServiceTest to include entries for system_instruction and
tool_calls, matching the keys denied by apply_consumer_policy_narrowing().
Strengthen the loop assertions to verify each case’s exact expected forbidden
error code rather than only checking the forbidden_ prefix.
- Around line 59-63: Update the teardown cleanup around managed_profile_keys to
delete each tracked profile’s tombstone within the existing loop, deriving the
option name with the service’s established tombstone prefix and hash format;
remove the hardcoded self::INTEGRATION deletion, then retain managed profile
deletion and reset the tracking array.
- Around line 470-479: Extend the handoff validation tests around inspect_job
and normalise_handoff to cover an intent outside the four-value allowlist,
missing or empty reason, and non-array handoff; assert each DTO omits the
handoff key. Also add a plain non-JSON reply case and assert it remains
supported without a handoff entry, while preserving the existing valid-intent
assertions.
- Around line 206-220: Update the test around ensure_profile and
Agent::get_by_managed_profile_key to use two managed profile keys whose
sanitize_title() results are identical, such as variants differing only by
characters WordPress removes or normalizes. Keep the existing assertions
verifying both profiles are created, retrieved, and receive different agent
slugs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 44e85667-c350-43dd-bae6-32141ab85ab3

📥 Commits

Reviewing files that changed from the base of the PR and between e2426b5 and 89c9bd3.

📒 Files selected for processing (18)
  • includes/Abilities/KnowledgeAbilities.php
  • includes/Contracts/CustomerAgentRuntimeInterface.php
  • includes/Core/AgentLoop.php
  • includes/Core/CustomerAgentPromptComposer.php
  • includes/Core/Database.php
  • includes/Models/Agent.php
  • includes/Models/CustomerAgentRuntimeRepository.php
  • includes/Models/DTO/AgentRow.php
  • includes/REST/SessionController.php
  • includes/Services/CustomerAgentRuntimeService.php
  • includes/Tools/ToolDiscovery.php
  • tests/SdAiAgent/Abilities/KnowledgeAbilitiesTest.php
  • tests/SdAiAgent/Core/CustomerAgentPromptComposerTest.php
  • tests/SdAiAgent/Core/DatabaseSchemaTest.php
  • tests/SdAiAgent/Models/AgentTest.php
  • tests/SdAiAgent/REST/PublicChatControllerTest.php
  • tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php
  • tests/SdAiAgent/Tools/ToolDiscoveryTest.php

Comment thread includes/Services/CustomerAgentRuntimeService.php Outdated
Comment thread includes/Services/CustomerAgentRuntimeService.php Outdated
Comment thread includes/Services/CustomerAgentRuntimeService.php
Comment thread includes/Services/CustomerAgentRuntimeService.php Outdated
Comment thread includes/Services/CustomerAgentRuntimeService.php
Comment thread tests/SdAiAgent/Services/CustomerAgentRuntimeServiceTest.php
@superdav42

Copy link
Copy Markdown
Contributor Author

CLAIM_RELEASED reason=worker_complete runner=superdav42 ts=2026-07-24T20:33:55Z aidevops_version=3.32.180 opencode_version=1.18.4

@superdav42 superdav42 added status:available Task is available for claiming and removed status:in-review Non-draft PR ready for review/merge labels Jul 24, 2026
@superdav42

Copy link
Copy Markdown
Contributor Author

CI repair feedback routed to issue #2321

This worker PR had terminal failed CI checks. The check details have been appended
to the linked issue body so the next worker can address them.

Terminal failed checks:

Closed by deterministic merge pass (pulse-merge.sh).

@superdav42 superdav42 closed this Jul 24, 2026
@superdav42 superdav42 added the ci-feedback-routed Worker PR with failing CI routed to linked issue for re-dispatch label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-feedback-routed Worker PR with failing CI routed to linked issue for re-dispatch origin:worker-takeover Worker took over from interactive session status:available Task is available for claiming

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a safely managed customer-support agent profile

1 participant