Skip to content

fix:agent clients lack timeout and retry logic hang indefinitely when server is unresponsive#701

Merged
unclesp1d3r merged 27 commits into
mainfrom
464-agent-clients-lack-timeout-and-retry-logic-hang-indefinitely-when-server-is-unresponsive
Mar 13, 2026
Merged

fix:agent clients lack timeout and retry logic hang indefinitely when server is unresponsive#701
unclesp1d3r merged 27 commits into
mainfrom
464-agent-clients-lack-timeout-and-retry-logic-hang-indefinitely-when-server-is-unresponsive

Conversation

@unclesp1d3r

@unclesp1d3r unclesp1d3r commented Mar 12, 2026

Copy link
Copy Markdown
Owner

This pull request introduces new agent definitions and configuration updates to support agent-native architecture reviews, Ankane-style README generation, and architectural strategy analysis. It also adds configuration for Tessl-managed files and MCP server integration across multiple tools. The most important changes are grouped below by theme.

Agent Definitions and Reviewers:

  • Added .github/agents/agent-native-reviewer.agent.md for reviewing agent-native architecture, ensuring parity between agent and user actions, context access, and shared workspace principles.
  • Added .github/agents/ankane-readme-writer.agent.md for generating Ruby gem READMEs in Ankane style, enforcing concise, imperative documentation with strict formatting rules.
  • Added .github/agents/architecture-strategist.agent.md for architectural analysis of code changes, focusing on pattern compliance, design integrity, and system evolution.

Tessl and MCP Server Configuration:

  • Added .claude/settings.json to enable layered-rails@palkan-skills and compound-engineering@compound-engineering-plugin plugins.
  • Updated .codex/config.toml, .cursor/mcp.json, and .gemini/settings.json to configure MCP server integration for Tessl, standardizing agent communication via the tessl command. [1] [2]

Tessl-Managed File Patterns:

  • Added .gitignore entries in .claude/skills, .codex/skills, .cursor/skills, and .gemini/skills to ignore Tessl-managed files and patterns, ensuring clean repository state.

These changes collectively enhance agent functionality, documentation quality, and system architecture review capabilities.

Summary by CodeRabbit

  • New Features

    • Unauthenticated client health-check endpoint.
    • UI action to expire agent benchmarks.
    • Client configuration now includes resilience recommendations (timeouts, retry, circuit breaker).
    • New public ErrorMetadata schema for agent error payloads.
  • Documentation

    • Expanded API reference and troubleshooting with resilience and error-handling guidance.
    • Numerous new agent-spec guidance documents.
  • Tests

    • Request specs added/updated for health, client config, tasks, and agents.
  • Chores

    • Dependency updates, CI/security workflows, and tooling/config manifests.

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
…ngs to client configuration

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
…utability

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
…onment

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
…ecurity, and analysis

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
…tasks_controller

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
…ntions

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
@unclesp1d3r unclesp1d3r self-assigned this Mar 12, 2026
Copilot AI review requested due to automatic review settings March 12, 2026 06:09
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Mar 12, 2026
…ic-hang-indefinitely-when-server-is-unresponsive
@dosubot dosubot Bot added the agents Agent management and monitoring label Mar 12, 2026
@coderabbitai

coderabbitai Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds many agent-specification docs and tooling configs for a "tessl" MCP server, introduces an unauthenticated client health endpoint and client resilience configuration, refactors task-assignment logic and agent activation, adds an expire-benchmarks UI/action and route, updates OpenAPI/specs/tests, adjusts broadcasts/caching in Agent model/views, and upgrades dependencies and CI workflows.

Changes

Cohort / File(s) Summary
Agent spec docs
.github/agents/*
Added ~27 agent-specification Markdown files defining reviewer personas, workflows, checklists, and output formats (security, data, design, migration, performance, etc.).
MCP / Tessl tooling
.claude/settings.json, .codex/config.toml, .cursor/mcp.json, .gemini/settings.json, .mcp.json, tessl.json, .*/skills/.gitignore
Configured a stdio MCP server entry named tessl across multiple tool configs, added tessl manifest and tessl-related .gitignore rules.
Agent lifecycle / UI / routing
app/models/agent.rb, app/views/agents/_capabilities_tab.html.erb, app/controllers/agents_controller.rb, app/models/ability.rb, config/routes.rb, spec/requests/agents_spec.rb
Added CONFIGURATION_BROADCAST_FIELDS, conditional tab broadcasting, removed Agent#new_task, added expire benchmarks route/action and ability rule, updated view caching and added UI button plus tests for expire flow.
Task assignment & activation
app/services/task_assignment_service.rb, app/controllers/api/v1/client/tasks_controller.rb, spec/requests/api/v1/client/tasks_spec.rb
Refactored task queries to scoped SKIP LOCKED usage and optional project filtering; controller uses TaskAssignmentService.find_next_task and invokes helper to auto-activate pending agents with benchmarks; added tests for activation behavior.
Client health & resilience
app/controllers/api/v1/client/health_controller.rb, config/routes/client_api.rb, app/views/api/v1/client/configuration.json.jbuilder, config/configs/application_config.rb, spec/requests/api/v1/client/health_spec.rb, spec/requests/api/v1/client_spec.rb
Added unauthenticated GET /api/v1/client/health with DB check; introduced resilience config attributes (timeouts, retry, circuit breaker) with validation and exposed them in client configuration responses and tests.
OpenAPI / specs
spec/swagger_helper.rb, swagger/v1/swagger.json, spec/requests/api/v1/client/agents_spec.rb
Added ErrorMetadata schema and replaced inline metadata refs; documented new health endpoint and resilience response fields in OpenAPI and tests.
Views, docs & repo config
AGENTS.md, GOTCHAS.md, docs/api-reference-agent-auth.md, docs/README.md, .mdformat.toml, .github/skills/.gitignore
Docs updated with resilience guidance, unauthenticated endpoint notes, runtime mutability rules, gotchas, and mdformat exclusions for agent/skill dirs.
Workflows & security
.github/workflows/check_security_vulnerability.yml, .github/workflows/dep.yml
Added DevSkim SARIF upload workflow and Dependency Review workflow with fail-on-severity and license deny rules.
Dependencies
Gemfile
Bumped many gem versions across runtime, dev, and test groups (numerous version updates and replacements).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client as Agent Client
    participant API as Client Task API
    participant Service as TaskAssignmentService
    participant Agent as Agent Model
    participant DB as Database
    participant UI as Browser UI

    Client->>API: GET /api/v1/client/tasks/new
    API->>Service: find_next_task()
    Service->>DB: scoped query (project filter?, FOR UPDATE SKIP LOCKED)
    DB-->>Service: task or nil
    Service-->>API: task payload
    API->>Agent: activate_pending_agent_with_benchmarks() (side effect)
    Agent->>DB: record activation / log
    API-->>Client: task response

    UI->>API: POST /agents/:id/expire_benchmarks
    API->>Agent: delete hashcat_benchmarks
    Agent->>Agent: check_benchmark_age()
    API-->>UI: redirect to agent#show with notice
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

agent-system, api, bug, documentation

Poem

🐰 I hopped through configs and docs so bright,

Health pings and retries tucked in the night.
Benchmarks cleared with a soft little thump,
Tessl hums, agents wake, the tasks jump.
A rabbit's small cheer — all systems light.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix being implemented: adding timeout and retry logic to prevent agent clients from hanging indefinitely when the server is unresponsive.
Docstring Coverage ✅ Passed Docstring coverage is 93.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 464-agent-clients-lack-timeout-and-retry-logic-hang-indefinitely-when-server-is-unresponsive
📝 Coding Plan for PR comments
  • Generate coding plan

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

@github-advanced-security

Copy link
Copy Markdown
Contributor

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@mergify

mergify Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?:

🟢 CI must pass

Wonderful, this rule succeeded.

All CI checks must pass. This protection prevents manual merges that bypass the merge queue.

  • check-success = DCO
  • check-success = lint
  • check-success = lint_api
  • check-success = scan_ruby
  • check-success = test

🟢 Do not merge outdated PRs

Wonderful, this rule succeeded.

Make sure PRs are within 10 commits of the base branch before merging

  • #commits-behind <= 10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the client API to better support resilient agent connectivity (timeouts/retries/circuit breaker recommendations + a health probe), while also introducing several operational/tooling additions (Tessl/MCP config, new review agents) and some UI/admin improvements around agent benchmarks and Turbo broadcasts.

Changes:

  • Add an unauthenticated client health endpoint and document it in OpenAPI + rswag.
  • Expose server-recommended HTTP resilience settings from GET /api/v1/client/configuration backed by ApplicationConfig.
  • Improve agent UI behavior (expire benchmarks action, safer fragment caching, reduced Turbo broadcast scope) and adjust task assignment to allow agents with no project assignments to work across projects.

Reviewed changes

Copilot reviewed 64 out of 65 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tessl.json Adds Tessl dependency pin/config.
swagger/v1/swagger.json Adds ErrorMetadata schema refactor; documents new health endpoint; adds resilience config fields.
spec/swagger_helper.rb Defines ErrorMetadata; adds DevSkim ignore annotations for MD5 wording.
spec/requests/api/v1/client_spec.rb Updates configuration schema + asserts new resilience defaults in response.
spec/requests/api/v1/client/health_spec.rb Adds rswag spec for unauthenticated health endpoint.
spec/requests/api/v1/client/agents_spec.rb Switches error metadata schema to $ref for reuse.
docs/api-reference-agent-auth.md Expands API reference (TOC + resilience recommendation docs).
docs/README.md Updates docs index description for agent API reference.
config/routes/client_api.rb Routes new GET /api/v1/client/health.
config/routes.rb Adds member route POST /agents/:id/expire_benchmarks.
config/configs/application_config.rb Adds resilience-related config values + validation/coercion.
app/views/api/v1/client/configuration.json.jbuilder Emits recommended_timeouts, recommended_retry, recommended_circuit_breaker.
app/views/agents/_capabilities_tab.html.erb Adds “Expire Benchmarks” button; reworks caching to avoid safe_can? cache poisoning.
app/services/task_assignment_service.rb Makes project scoping conditional so agents with no projects can work globally; refactors query building.
app/models/agent.rb Adds targeted broadcast guards for configuration/capabilities tabs; removes model→service call for task assignment.
app/models/ability.rb Grants expire_benchmarks on own agents.
app/controllers/api/v1/client/tasks_controller.rb Uses TaskAssignmentService directly; auto-activates pending agents with benchmarks.
app/controllers/api/v1/client/health_controller.rb Implements unauthenticated JSON health check with DB probe and degraded status handling.
app/controllers/agents_controller.rb Adds expire_benchmarks action to clear benchmarks and force re-benchmarking.
Gemfile.lock Updates multiple gem versions (dependency refresh).
Gemfile Tightens/bumps gem version constraints to match lockfile.
GOTCHAS.md Adds operational/testing/docs gotchas (rswag required props, unauth endpoints guidance, Turbo cache + safe_can?, etc.).
AGENTS.md Updates test DB URL guidance; documents unauth endpoint patterns and architectural constraints.
.tessl/.gitignore Ignores Tessl-managed artifacts.
.mdformat.toml Excludes agent/skills directories from formatting; aligns config formatting.
.mcp.json Adds MCP server config for Tessl.
.github/workflows/dep.yml Adds Dependency Review workflow.
.github/workflows/check_security_vulnerability.yml Adds DevSkim scan workflow + SARIF upload.
.github/skills/.gitignore Ignores Tessl-managed skill files.
.github/agents/spec-flow-analyzer.agent.md Adds reviewer agent definition.
.github/agents/security-sentinel.agent.md Adds reviewer agent definition.
.github/agents/schema-drift-detector.agent.md Adds reviewer agent definition.
.github/agents/repo-research-analyst.agent.md Adds reviewer agent definition.
.github/agents/pr-comment-resolver.agent.md Adds reviewer agent definition.
.github/agents/performance-oracle.agent.md Adds reviewer agent definition.
.github/agents/pattern-recognition-specialist.agent.md Adds reviewer agent definition.
.github/agents/lint.agent.md Adds reviewer agent definition.
.github/agents/learnings-researcher.agent.md Adds reviewer agent definition.
.github/agents/kieran-typescript-reviewer.agent.md Adds reviewer agent definition.
.github/agents/kieran-rails-reviewer.agent.md Adds reviewer agent definition.
.github/agents/kieran-python-reviewer.agent.md Adds reviewer agent definition.
.github/agents/julik-frontend-races-reviewer.agent.md Adds reviewer agent definition.
.github/agents/git-history-analyzer.agent.md Adds reviewer agent definition.
.github/agents/framework-docs-researcher.agent.md Adds reviewer agent definition.
.github/agents/figma-design-sync.agent.md Adds reviewer agent definition.
.github/agents/dhh-rails-reviewer.agent.md Adds reviewer agent definition.
.github/agents/design-iterator.agent.md Adds reviewer agent definition.
.github/agents/design-implementation-reviewer.agent.md Adds reviewer agent definition.
.github/agents/deployment-verification-agent.agent.md Adds reviewer agent definition.
.github/agents/data-migration-expert.agent.md Adds reviewer agent definition.
.github/agents/data-integrity-guardian.agent.md Adds reviewer agent definition.
.github/agents/code-simplicity-reviewer.agent.md Adds reviewer agent definition.
.github/agents/bug-reproduction-validator.agent.md Adds reviewer agent definition.
.github/agents/best-practices-researcher.agent.md Adds reviewer agent definition.
.github/agents/architecture-strategist.agent.md Adds reviewer agent definition.
.github/agents/ankane-readme-writer.agent.md Adds reviewer agent definition.
.github/agents/agent-native-reviewer.agent.md Adds reviewer agent definition.
.gemini/skills/.gitignore Ignores Tessl-managed skill files.
.gemini/settings.json Adds Tessl MCP server config.
.cursor/skills/.gitignore Ignores Tessl-managed skill files.
.cursor/mcp.json Adds Tessl MCP server config.
.codex/skills/.gitignore Ignores Tessl-managed skill files.
.codex/config.toml Adds Tessl MCP server config.
.claude/skills/.gitignore Ignores Tessl-managed skill files.
.claude/settings.json Enables specified Claude plugins.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tessl.json
Comment on lines +1 to +3
{
"name": "my-project",
"dependencies": {

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

PR title/description don’t match the actual code changes: this PR adds client resilience recommendations + a new unauthenticated health endpoint, plus UI/admin changes (expire benchmarks, broadcast behavior) and broad dependency/workflow updates. Consider updating the PR description (or splitting into smaller PRs) so reviewers and release notes reflect the real scope.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Acknowledged. The PR scope grew organically from agent resilience work into related agent lifecycle improvements. The PR description has been updated to reflect the actual scope.

Comment thread app/models/agent.rb
Comment on lines +91 to +95
# Fields whose changes should trigger a configuration tab broadcast.
CONFIGURATION_BROADCAST_FIELDS = %w[
enabled client_signature last_ipaddress advanced_configuration
custom_label operating_system
].freeze

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

CONFIGURATION_BROADCAST_FIELDS doesn’t include fields rendered in the configuration tab like user_id (and potentially other displayed attributes). If an admin reassigns an agent to a different user, broadcast_tab_updates won’t refresh the configuration tab, leaving stale UI until a manual reload. Consider adding any configuration-tab-affecting attributes (e.g., user_id) to this list or switching to a more explicit predicate for when to broadcast configuration updates.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Good catch — added user_id to CONFIGURATION_BROADCAST_FIELDS in this push.

Comment thread app/models/agent.rb Outdated
Comment thread app/services/task_assignment_service.rb Outdated
Comment thread app/controllers/api/v1/client/health_controller.rb Outdated
Comment on lines +236 to +244
def activate_pending_agent_with_benchmarks
return unless @agent.pending? && @agent.hashcat_benchmarks.exists?
return unless @agent.activate

Rails.logger.info(
"[AgentLifecycle] auto_activate: agent_id=#{@agent.id} " \
"reason=pending_with_benchmarks benchmark_count=#{@agent.hashcat_benchmarks.count} " \
"timestamp=#{Time.zone.now}"
)

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

activate_pending_agent_with_benchmarks does an exists? check and then logs @agent.hashcat_benchmarks.count, which issues an additional query. Since this endpoint can be hit frequently, consider collapsing this to a single query (e.g., fetch count once and use it both for the predicate and logging) to avoid extra DB load.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Good catch — collapsed the exists? + count into a single count query, reusing the result for both the predicate and logging.

Comment thread swagger/v1/swagger.json
Comment on lines +1288 to +1323
"200": {
"description": "healthy",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Overall health status (ok or degraded)"
},
"api_version": {
"type": "integer",
"description": "API version"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "Server timestamp"
},
"database": {
"type": "string",
"description": "Database health (healthy or unhealthy)"
}
},
"required": [
"status",
"api_version",
"timestamp",
"database"
]
}
}
}
}
}

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

GET /api/v1/client/health can return 503 Service Unavailable when status is degraded (per the controller), but the OpenAPI spec only documents a 200 response. Add a 503 response (with the same schema) so clients and generated SDKs can handle degraded health correctly.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed — added a response(503, "degraded") block to the rswag spec. Swagger will be regenerated in this push.

Comment on lines +19 to +27
response(200, "healthy") do
schema type: :object,
properties: {
status: { type: :string, description: "Overall health status (ok or degraded)" },
api_version: { type: :integer, description: "API version" },
timestamp: { type: :string, format: "date-time", description: "Server timestamp" },
database: { type: :string, description: "Database health (healthy or unhealthy)" }
},
required: %i[status api_version timestamp database]

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

The health endpoint implementation returns 503 when the database check fails, but the rswag spec only defines/tests the 200 response. Add a response(503, ...) case (stubbing the DB check to fail) so the documented behavior stays in sync with the controller.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed — added a response(503, ...) rswag test case that stubs the DB check to fail.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 15

🧹 Nitpick comments (13)
.codex/config.toml (1)

1-4: Drop type = "stdio" from the Codex MCP stanza.

Codex’s config reference and sample config define MCP transport implicitly: stdio servers use command/args, and HTTP servers use url. I don’t see mcp_servers.<id>.type in the documented schema, so this key risks being ignored or rejected by some Codex builds. (developers.openai.com)

Suggested change
 [mcp_servers.tessl]
-type = "stdio"
 command = "tessl"
 args = [ "mcp", "start" ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.codex/config.toml around lines 1 - 4, Remove the unsupported "type =
\"stdio\"" key from the Codex MCP stanza [mcp_servers.tessl]; retain the
existing "command = \"tessl\"" and "args = [ \"mcp\", \"start\" ]" lines so the
MCP transport is defined implicitly via command/args as per the Codex config
schema.
.github/workflows/dep.yml (1)

17-17: Avoid introducing a deprecated license filter in a new workflow.

Line 17 uses deny-licenses, which the action docs mark as deprecated for possible removal in a future major release. I'd switch this new workflow to allow-licenses or move the policy into an external config before this becomes upgrade debt. (github.com)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/dep.yml at line 17, The workflow uses the deprecated
deny-licenses key; update the dependency-review action configuration by removing
or replacing deny-licenses and instead use allow-licenses (or move license
policy into an external configuration file consumed by the action) so the new
workflow doesn't introduce deprecated configuration; search for the
deny-licenses entry and replace it with an appropriate allow-licenses whitelist
or reference to an external policy per the dependency-review-action docs.
.mdformat.toml (1)

10-13: Cover the other Tessl-managed skill directories here too.

Lines 10-13 exclude .github/* and .kiro/*, but this PR also introduces Tessl-managed content under .claude/skills, .codex/skills, .cursor/skills, and .gemini/skills. Leaving those out means mdformat can still rewrite generated files there and create avoidable churn.

Suggested diff
 exclude = [
     "venv/**",
     "**/node_modules/**",
     "**/*.txt",
     "**/*.mdc",
     "**/*.tpl.md",
     "**/CHANGELOG.md",
     "target/**",
     "megalinter-reports/**",
     ".github/agents/**",
     ".github/skills/**",
+    ".claude/skills/**",
+    ".codex/skills/**",
+    ".cursor/skills/**",
+    ".gemini/skills/**",
     ".kiro/agents/**",
     ".kiro/skills/**",
 ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.mdformat.toml around lines 10 - 13, The mdformat exclude list currently
includes ".github/agents/**", ".github/skills/**", ".kiro/agents/**", and
".kiro/skills/**" but misses other Tessl-managed directories, so update the
exclude patterns to also cover the introduced generated directories (e.g. add
".claude/skills/**", ".claude/agents/**", ".codex/skills/**",
".codex/agents/**", ".cursor/skills/**", ".cursor/agents/**",
".gemini/skills/**", ".gemini/agents/**") so mdformat won't rewrite generated
files there; modify the exclusion array in .mdformat.toml to include these new
glob patterns alongside the existing ".github/*" and ".kiro/*" entries.
.github/agents/lint.agent.md (1)

13-17: Separate Brakeman findings from the lint auto-fix path.

standardrb/erblint can safely flow into auto-fix + style commits, but bin/brakeman findings are security issues and usually need deliberate review. Folding them into “Take Action: Commit fixes with style: linting” risks misclassifying security remediations as cosmetic changes.

Suggested wording
 2. **Execute Appropriate Tools**:
    - For Ruby files: `bundle exec standardrb` for checking, `bundle exec standardrb --fix` for auto-fixing
    - For ERB templates: `bundle exec erblint --lint-all` for checking, `bundle exec erblint --lint-all --autocorrect` for auto-fixing
-   - For security: `bin/brakeman` for vulnerability scanning
+   - For security: `bin/brakeman` for vulnerability scanning and separate reporting
 3. **Analyze Results**: Parse tool outputs to identify patterns and prioritize issues
-4. **Take Action**: Commit fixes with `style: linting`
+4. **Take Action**:
+   - Auto-fix and commit lint-only issues with `style: linting`
+   - Report Brakeman findings separately for manual review/remediation
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/agents/lint.agent.md around lines 13 - 17, Separate Brakeman
security findings from the auto-fix lint flow: update the "Take Action" guidance
so that `standardrb` and `erblint` auto-fixes still commit with `style:
linting`, but `bin/brakeman` results are routed to a distinct review/PR process
(e.g., label or branch) requiring manual triage and a different commit message
or workflow, and ensure the doc mentions `bin/brakeman` explicitly as not to be
auto-fixed or committed under `style: linting`.
.github/agents/pr-comment-resolver.agent.md (1)

47-58: Require targeted validation before reporting “Resolved.”

The current flow lets the agent confirm resolution after a manual double-check, but without running the narrowest relevant tests/lints. For PR feedback that changes behavior, that is too easy to mark resolved prematurely.

Suggested wording
 4. **Verify the Resolution**: After making changes:
 
    - Double-check that the change addresses the original comment
    - Ensure no unintended modifications were made
    - Verify the code still follows project conventions
+   - Run the narrowest relevant validation available (tests, lint, type checks) before reporting success
 
 5. **Report the Resolution**: Provide a clear, concise summary that includes:
@@
-   - A confirmation that the issue has been resolved
+   - A confirmation that the issue has been resolved, including what validation was run
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/agents/pr-comment-resolver.agent.md around lines 47 - 58, Update the
"Verify the Resolution" and "Report the Resolution" steps to require running
targeted validation (e.g., the smallest reproducing unit of tests, focused
linters, or a specific test file/command) before marking a comment as resolved;
specifically, modify the text under the "Verify the Resolution" and "Report the
Resolution" headings to instruct the agent to run the narrowest relevant
tests/lints and confirm they pass, then include in the "Report the Resolution"
summary which exact test/lint command or file was run and its result before
stating the issue is resolved.
.github/workflows/check_security_vulnerability.yml (1)

29-36: Action versions are valid and secure, but consider using v1 tag for DevSkim.

Both versions are current: microsoft/DevSkim-Action@v1.0.16 (latest as of May 2025) and github/codeql-action/upload-sarif@v4.32.6 (latest as of March 2026) have no known vulnerabilities. However, the DevSkim-Action README recommends pinning to the major-version tag v1 instead of the specific release to benefit from periodic security patches while maintaining compatibility. The current pinned version is safe for reproducibility; switching to v1 would improve the security update posture.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/check_security_vulnerability.yml around lines 29 - 36,
Update the DevSkim action version string to use the major-version tag
recommended by the README: replace the hard-pinned reference
"microsoft/DevSkim-Action@v1.0.16" with "microsoft/DevSkim-Action@v1" (leave the
github/codeql-action/upload-sarif@v4.32.6 step unchanged); this keeps
reproducibility while allowing upstream security patches for the DevSkim action.
config/configs/application_config.rb (1)

110-118: Validation is correct but consider zero as an edge case.

The validation correctly ensures positive integers. One consideration: recommended_retry_initial_delay: 0 might be a valid configuration for "no delay between retries" in some use cases. If zero should be allowed for delay-related settings, consider using value >= 0 for those specific attributes.

💡 Optional: Allow zero for delay settings if needed

If zero-delay retries are a valid use case:

 def validate_resilience_settings
+  non_zero_attrs = RESILIENCE_ATTRIBUTES - %i[recommended_retry_initial_delay]
   RESILIENCE_ATTRIBUTES.each do |attr|
     value = public_send(attr)
-    unless value.is_a?(Integer) && value.positive?
+    min_value = non_zero_attrs.include?(attr) ? 1 : 0
+    unless value.is_a?(Integer) && value >= min_value
       raise Anyway::Config::ValidationError,
             "#{attr} must be a positive integer, got: #{value.inspect}"
     end
   end
 end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/configs/application_config.rb` around lines 110 - 118, The current
validate_resilience_settings method rejects zero for all RESILIENCE_ATTRIBUTES;
if some attributes (e.g. recommended_retry_initial_delay or other delay-related
keys) should allow zero, update validate_resilience_settings to treat those
specially: define a small set/array like zero_allowed_attributes (including
recommended_retry_initial_delay) and when iterating RESILIENCE_ATTRIBUTES use
value.is_a?(Integer) && (zero_allowed_attributes.include?(attr) ? value >= 0 :
value.positive?) to validate; keep raising the same
Anyway::Config::ValidationError with the existing message when validation fails
so behavior is unchanged for other attributes.
.github/agents/figma-design-sync.agent.md (1)

79-82: Scope this rule to layout sections instead of every component.

Making w-full and parent-owned padding/max-width an absolute requirement will push the agent to strip legitimate sizing contracts from reusable leaf components, not just page sections. I'd phrase this as the default for top-level layout/section components, or “unless the component’s existing contract says otherwise.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/agents/figma-design-sync.agent.md around lines 79 - 82, Update the
rule text in the bullet list that currently mandates "Components should ALWAYS
be full width (`w-full`)..." etc., to scope it to top-level layout/section
components rather than every component; rephrase to say something like
"Top-level layout/section components should default to full width (`w-full`) and
avoid outer padding/max-width—unless the component's existing sizing contract
specifies otherwise," and similarly clarify that width constraints and
horizontal padding should typically be handled by parent wrapper divs for those
top-level sections; edit the same bullet group so the guidance applies to
section/layout components only and preserves exceptions for reusable leaf
components.
config/routes/client_api.rb (1)

10-30: Update the route documentation comment to include the new health endpoint.

The route comment block (lines 10-28) documents all routes but doesn't include the newly added health endpoint. Consider adding:

# - GET    /client/health                           -> health#index
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/routes/client_api.rb` around lines 10 - 30, Update the top comment
block documenting routes to include the new health endpoint by adding a line
like "# - GET    /client/health                           -> health#index" so
the documented routes reflect the actual namespace :client route and the
health#index action; modify the comment near the existing route list (where
other client routes are documented) to include this entry.
app/controllers/agents_controller.rb (2)

78-87: Consider alphabetical method ordering.

Per coding guidelines, methods should be in alphabetical order except for initialize and CRUD actions. expire_benchmarks should be placed after edit and before index to maintain alphabetical ordering.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/controllers/agents_controller.rb` around lines 78 - 87, Move the
expire_benchmarks method within AgentsController so methods follow the project's
alphabetical ordering rules (exceptions: initialize and standard CRUD actions);
specifically, relocate def expire_benchmarks to sit after the def edit method
and before the def index method in the class, keeping the method body and
existing redirect/notice behavior unchanged.

78-87: Add YARD documentation for the public expire_benchmarks action.

Per coding guidelines, all public methods should be documented using YARD syntax.

📝 Proposed YARD documentation
+  # POST /agents/1/expire_benchmarks
+  #
+  # Deletes all benchmarks for the agent and transitions it to pending,
+  # forcing the agent to re-benchmark on its next heartbeat.
+  #
+  # `@return` [void] Redirects to the agent's capabilities tab with a notice.
   def expire_benchmarks
     `@agent.hashcat_benchmarks.destroy_all`
     `@agent.check_benchmark_age`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/controllers/agents_controller.rb` around lines 78 - 87, Add a YARD
docblock above the public controller action expire_benchmarks describing its
behavior (deletes all hashcat benchmarks for the agent and transitions it to
pending so it re-benchmarks on next heartbeat), include tags such as `@return`
[void] (or `@return` [ActionController::Redirecting] per project conventions) and
`@route` or `@see` if your style guide requires route information, and indicate any
side effects (redirects to agent_url with anchor "capabilities" and a notice).
Use the method name expire_benchmarks to locate the action and place the YARD
comment immediately above its def line.
app/controllers/api/v1/client/health_controller.rb (1)

24-39: Add YARD documentation for the index method.

Per coding guidelines, all public methods should be documented using YARD syntax.

📝 Proposed YARD documentation
+  # Returns server health status for agent connectivity checks.
+  #
+  # Performs a lightweight database connectivity test and returns
+  # health status as JSON. No authentication required.
+  #
+  # `@return` [void] Renders JSON with status, api_version, timestamp, and database health.
+  #   Returns HTTP 200 when healthy, 503 when degraded.
   # GET /api/v1/client/health
   def index
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/controllers/api/v1/client/health_controller.rb` around lines 24 - 39, Add
a YARD docstring above the public index method in HealthController describing
its purpose, HTTP route (GET /api/v1/client/health), return type (renders JSON),
keys returned in the payload (status, api_version, timestamp, database), and
possible HTTP status codes (:ok and :service_unavailable) — target the index
method symbol and place the `@return` and `@note` tags as appropriate so the index
method is fully documented per YARD standards.
spec/requests/api/v1/client/health_spec.rb (1)

19-51: Consider adding a test for the degraded/503 response.

The health controller returns a 503 status when the database is unhealthy. Consider adding a test case for this scenario to ensure the degraded state is properly documented in the OpenAPI spec.

🧪 Proposed test for degraded state
response(503, "degraded") do
  schema type: :object,
         properties: {
           status: { type: :string, description: "Overall health status (ok or degraded)" },
           api_version: { type: :integer, description: "API version" },
           timestamp: { type: :string, format: "date-time", description: "Server timestamp" },
           database: { type: :string, description: "Database health (healthy or unhealthy)" }
         },
         required: %i[status api_version timestamp database]

  before do
    allow(ActiveRecord::Base.connection).to receive(:execute).and_raise(StandardError.new("Connection failed"))
  end

  run_test! do
    expect(response).to have_http_status(:service_unavailable)
    data = JSON.parse(response.body, symbolize_names: true)
    expect(data[:status]).to eq("degraded")
    expect(data[:database]).to eq("unhealthy")
  end
end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spec/requests/api/v1/client/health_spec.rb` around lines 19 - 51, Add a new
response(503, "degraded") test block next to the existing response(200,
"healthy") in spec/requests/api/v1/client/health_spec.rb that mirrors the
healthy schema, but stubs the DB check to fail; inside the block use a before
hook to make ActiveRecord::Base.connection.execute raise (e.g.
StandardError("Connection failed")), call run_test!, and assert
expect(response).to have_http_status(:service_unavailable) and that the parsed
response body has status "degraded" and database "unhealthy" (keeping the same
timestamp and api_version assertions as appropriate).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/agents/ankane-readme-writer.agent.md:
- Around line 3-5: The agent's config currently grants broad tool access via the
"tools: '*'" and allows automatic scope granting with "infer: true"; restrict
this by replacing "tools: '*'" with an explicit minimal list of
documentation-related tools (e.g., the specific read and write tools your
platform uses for editing README files) and set "infer: false" so scopes are not
auto-granted; update the keys in .github/agents/ankane-readme-writer.agent.md
(tools and infer) accordingly to only include the necessary read/write tools for
README edits.
- Around line 28-32: Add an explicit rule to the numbered prompt list that
preserves existing project-specific sections unless the user explicitly requests
their removal: update the list around the existing items (the numbered rules 1–5
and the line "Preserve project-specific sections when reformatting existing
READMEs.") to include a new rule stating "Retain any nonstandard or
project-specific sections when reformatting; only remove them if the user
explicitly asks." Ensure the agent's "update" flow respects that rule (do not
drop custom sections by default) while keeping the other rules (imperative
voice, sentence length, exact section order, and "Remove ALL HTML comments")
intact.
- Line 68: Update the README template guidance to wrap placeholder tokens like
<gemname> and <user> in inline code formatting (e.g., `\<gemname\>`, `\<user\>`)
wherever they appear so they are rendered as literal placeholders instead of
being interpreted as HTML; search for the placeholder occurrences in the
ankane-readme-writer agent content and replace plain occurrences of "<gemname>"
and "<user>" with inline-code versions and ensure any similar tokens follow the
same inline code pattern.

In @.github/agents/deployment-verification-agent.agent.md:
- Around line 123-133: The code block under "Sample console verification"
contains a non-executable placeholder `old_column: [present values]`; update the
example so it can be pasted into a Rails console by replacing the placeholder
with a real predicate (e.g., use Record.where(new_column:
nil).where.not(old_column: nil).count) or move the placeholder text outside the
fenced ruby block and keep the console examples executable (targets: the
Record.where(...) and Record.order("RANDOM()").limit(10).pluck(...) lines).

In @.github/agents/git-history-analyzer.agent.md:
- Line 36: The current use of the literal command "git shortlog -sn --" returns
repo-wide authorship and must be scoped to the files being analyzed; change the
code that builds the git command (the invocation that currently uses "git
shortlog -sn --") to append the target path(s) (e.g., a variable like
targetPaths or pathsToAnalyze) after the "--", properly quoting/escaping
multiple paths, so the command becomes "git shortlog -sn -- <paths...>" and
handles single or multiple file/path inputs.

In @.github/agents/julik-frontend-races-reviewer.agent.md:
- Around line 19-24: Replace the incorrect agent name string
"julik-frontend-reviewer" in the example dialogue with the correct agent name
"julik-frontend-races-reviewer" so the prompt and assistant response match the
spec; update the quoted lines that mention the agent (e.g., the user/assistant
example block containing "julik-frontend-reviewer") to reference
"julik-frontend-races-reviewer" consistently.
- Around line 113-123: The timeout helper setTimeoutWithCancelation defines
handlerWithCancelation but mistakenly passes an undefined handler to setTimeout,
causing a ReferenceError; update the call inside setTimeoutWithCancelation to
pass handlerWithCancelation (and keep the existing cancelToken/cancel logic
intact) so the cancelable timer uses the correct function reference.

In @.github/agents/kieran-rails-reviewer.agent.md:
- Around line 18-25: The example block contains two "assistant:" entries inside
a single <example>, which breaks the one-response-per-example rule; update the
agent spec by splitting that <example> into two separate <example> blocks (one
with the assistant reply "I've refactored the EmailProcessor service to handle
attachments." and a second with "Let me have Kieran review these changes to the
EmailProcessor service.") or remove the redundant assistant line so each
<example> contains exactly one assistant response, and apply the same fix to the
similar occurrence mentioned around the other <example> (lines referenced in the
comment).

In @.github/agents/pattern-recognition-specialist.agent.md:
- Around line 38-43: The "Naming Convention Analysis" bullet merges "Constants
and configuration values" with the following instruction sentence; split this
into two list items so the list remains well-formed: keep the bullet for
"Constants and configuration values" as its own line and create a separate
bullet (or immediately following sentence) that starts with "Identify deviations
from established conventions and suggest improvements." Update the block
containing the heading "3. **Naming Convention Analysis**" and the sub-items
(Variables, Classes, Files, Constants) so each sub-item is a distinct list entry
and the instruction to identify deviations is not appended to the Constants
line.

In @.github/agents/performance-oracle.agent.md:
- Around line 3-5: Replace the broad tools wildcard under the YAML key tools
(currently set to '*') with the minimal, explicit read/search tool set the agent
actually needs (instead of tools: '*'); edit the same block where infer: true
appears to enumerate only the specific tool identifiers used for analysis (e.g.,
file.read, file.search or the repository search/read tool names your system
uses) so the agent has least privilege.

In @.github/workflows/dep.yml:
- Around line 4-6: The workflow's permissions block only grants "contents: read"
which prevents the dependency-review-action from creating PR comments when
"comment-summary-in-pr: on-failure" is enabled; update the permissions section
to add "pull-requests: write" (or remove/disable the "comment-summary-in-pr:
on-failure" setting) so the dependency review can post comments. Locate the
permissions stanza (the "permissions" key and its "contents: read" entry) and
either add "pull-requests: write" alongside it or change the
dependency-review-action configuration (the "comment-summary-in-pr" option) to a
mode that doesn't require PR write permissions.

In `@AGENTS.md`:
- Around line 380-385: The fenced code block around the example view test is
missing a language specifier (MD040); update the block so the opening fence is
"```ruby" and ensure it closes with "```" so the snippet (e.g., render partial:
"agents/configuration_tab", locals: { agent: agent } / expect(rendered).to
have_content("Configuration")) is treated as Ruby, or alternatively convert the
snippet into consistent bullet points if it was not intended as code; also
ensure the note about stubbing safe_can? remains formatted consistently with the
chosen style.

In `@docs/api-reference-agent-auth.md`:
- Around line 593-611: Update the retry guidance to avoid blind retries on
non-idempotent endpoints: explicitly call out that mutating POSTs (e.g.,
accept_task, submit_crack, submit_error) must not be retried blindly and either
should be excluded from the "Retry? Yes" cases in the table or require an
idempotency key/request ID; add text describing the required idempotency header
semantics and server behavior (dedupe by idempotency key) or instruct clients to
mark these endpoints as non-retryable and only retry after explicit confirmation
from the server; keep the exponential-backoff + jitter recommendation for
idempotent operations and 3xx/5xx/429 cases but ensure the table rows and
surrounding prose clearly differentiate idempotent vs non-idempotent endpoints.
- Around line 15-22: Add the missing liveness probe documentation for GET
/api/v1/client/health: insert a TOC entry under the "Agent Authentication" (or
immediately before auth/config entries) linking to a new "GET
/api/v1/client/health" section, and create that section describing the endpoint
purpose (client liveness probe), expected HTTP response codes (200 OK with a
simple health JSON payload, 503 on unhealthy), required headers (if any), and a
minimal example response body so agents know to call it before fetching
auth/config. Ensure the new section title matches "GET /api/v1/client/health"
and the TOC anchor matches that title.
- Around line 595-597: The fenced code block containing the expression "delay =
min(initial_delay * 2^attempt, max_delay) + random(0, delay * 0.5)" is missing a
language label; update the markdown fence to include a language (e.g., "text")
so markdownlint MD040 is satisfied by changing ``` to ```text for that block.

---

Nitpick comments:
In @.codex/config.toml:
- Around line 1-4: Remove the unsupported "type = \"stdio\"" key from the Codex
MCP stanza [mcp_servers.tessl]; retain the existing "command = \"tessl\"" and
"args = [ \"mcp\", \"start\" ]" lines so the MCP transport is defined implicitly
via command/args as per the Codex config schema.

In @.github/agents/figma-design-sync.agent.md:
- Around line 79-82: Update the rule text in the bullet list that currently
mandates "Components should ALWAYS be full width (`w-full`)..." etc., to scope
it to top-level layout/section components rather than every component; rephrase
to say something like "Top-level layout/section components should default to
full width (`w-full`) and avoid outer padding/max-width—unless the component's
existing sizing contract specifies otherwise," and similarly clarify that width
constraints and horizontal padding should typically be handled by parent wrapper
divs for those top-level sections; edit the same bullet group so the guidance
applies to section/layout components only and preserves exceptions for reusable
leaf components.

In @.github/agents/lint.agent.md:
- Around line 13-17: Separate Brakeman security findings from the auto-fix lint
flow: update the "Take Action" guidance so that `standardrb` and `erblint`
auto-fixes still commit with `style: linting`, but `bin/brakeman` results are
routed to a distinct review/PR process (e.g., label or branch) requiring manual
triage and a different commit message or workflow, and ensure the doc mentions
`bin/brakeman` explicitly as not to be auto-fixed or committed under `style:
linting`.

In @.github/agents/pr-comment-resolver.agent.md:
- Around line 47-58: Update the "Verify the Resolution" and "Report the
Resolution" steps to require running targeted validation (e.g., the smallest
reproducing unit of tests, focused linters, or a specific test file/command)
before marking a comment as resolved; specifically, modify the text under the
"Verify the Resolution" and "Report the Resolution" headings to instruct the
agent to run the narrowest relevant tests/lints and confirm they pass, then
include in the "Report the Resolution" summary which exact test/lint command or
file was run and its result before stating the issue is resolved.

In @.github/workflows/check_security_vulnerability.yml:
- Around line 29-36: Update the DevSkim action version string to use the
major-version tag recommended by the README: replace the hard-pinned reference
"microsoft/DevSkim-Action@v1.0.16" with "microsoft/DevSkim-Action@v1" (leave the
github/codeql-action/upload-sarif@v4.32.6 step unchanged); this keeps
reproducibility while allowing upstream security patches for the DevSkim action.

In @.github/workflows/dep.yml:
- Line 17: The workflow uses the deprecated deny-licenses key; update the
dependency-review action configuration by removing or replacing deny-licenses
and instead use allow-licenses (or move license policy into an external
configuration file consumed by the action) so the new workflow doesn't introduce
deprecated configuration; search for the deny-licenses entry and replace it with
an appropriate allow-licenses whitelist or reference to an external policy per
the dependency-review-action docs.

In @.mdformat.toml:
- Around line 10-13: The mdformat exclude list currently includes
".github/agents/**", ".github/skills/**", ".kiro/agents/**", and
".kiro/skills/**" but misses other Tessl-managed directories, so update the
exclude patterns to also cover the introduced generated directories (e.g. add
".claude/skills/**", ".claude/agents/**", ".codex/skills/**",
".codex/agents/**", ".cursor/skills/**", ".cursor/agents/**",
".gemini/skills/**", ".gemini/agents/**") so mdformat won't rewrite generated
files there; modify the exclusion array in .mdformat.toml to include these new
glob patterns alongside the existing ".github/*" and ".kiro/*" entries.

In `@app/controllers/agents_controller.rb`:
- Around line 78-87: Move the expire_benchmarks method within AgentsController
so methods follow the project's alphabetical ordering rules (exceptions:
initialize and standard CRUD actions); specifically, relocate def
expire_benchmarks to sit after the def edit method and before the def index
method in the class, keeping the method body and existing redirect/notice
behavior unchanged.
- Around line 78-87: Add a YARD docblock above the public controller action
expire_benchmarks describing its behavior (deletes all hashcat benchmarks for
the agent and transitions it to pending so it re-benchmarks on next heartbeat),
include tags such as `@return` [void] (or `@return` [ActionController::Redirecting]
per project conventions) and `@route` or `@see` if your style guide requires route
information, and indicate any side effects (redirects to agent_url with anchor
"capabilities" and a notice). Use the method name expire_benchmarks to locate
the action and place the YARD comment immediately above its def line.

In `@app/controllers/api/v1/client/health_controller.rb`:
- Around line 24-39: Add a YARD docstring above the public index method in
HealthController describing its purpose, HTTP route (GET /api/v1/client/health),
return type (renders JSON), keys returned in the payload (status, api_version,
timestamp, database), and possible HTTP status codes (:ok and
:service_unavailable) — target the index method symbol and place the `@return` and
`@note` tags as appropriate so the index method is fully documented per YARD
standards.

In `@config/configs/application_config.rb`:
- Around line 110-118: The current validate_resilience_settings method rejects
zero for all RESILIENCE_ATTRIBUTES; if some attributes (e.g.
recommended_retry_initial_delay or other delay-related keys) should allow zero,
update validate_resilience_settings to treat those specially: define a small
set/array like zero_allowed_attributes (including
recommended_retry_initial_delay) and when iterating RESILIENCE_ATTRIBUTES use
value.is_a?(Integer) && (zero_allowed_attributes.include?(attr) ? value >= 0 :
value.positive?) to validate; keep raising the same
Anyway::Config::ValidationError with the existing message when validation fails
so behavior is unchanged for other attributes.

In `@config/routes/client_api.rb`:
- Around line 10-30: Update the top comment block documenting routes to include
the new health endpoint by adding a line like "# - GET    /client/health        
-> health#index" so the documented routes reflect the actual namespace :client
route and the health#index action; modify the comment near the existing route
list (where other client routes are documented) to include this entry.

In `@spec/requests/api/v1/client/health_spec.rb`:
- Around line 19-51: Add a new response(503, "degraded") test block next to the
existing response(200, "healthy") in spec/requests/api/v1/client/health_spec.rb
that mirrors the healthy schema, but stubs the DB check to fail; inside the
block use a before hook to make ActiveRecord::Base.connection.execute raise
(e.g. StandardError("Connection failed")), call run_test!, and assert
expect(response).to have_http_status(:service_unavailable) and that the parsed
response body has status "degraded" and database "unhealthy" (keeping the same
timestamp and api_version assertions as appropriate).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 99cbcc5b-e53a-461a-9cfe-af410b62749d

📥 Commits

Reviewing files that changed from the base of the PR and between 52ad520 and 7fbd76b.

⛔ Files ignored due to path filters (1)
  • Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (64)
  • .claude/settings.json
  • .claude/skills/.gitignore
  • .codex/config.toml
  • .codex/skills/.gitignore
  • .cursor/mcp.json
  • .cursor/skills/.gitignore
  • .gemini/settings.json
  • .gemini/skills/.gitignore
  • .github/agents/agent-native-reviewer.agent.md
  • .github/agents/ankane-readme-writer.agent.md
  • .github/agents/architecture-strategist.agent.md
  • .github/agents/best-practices-researcher.agent.md
  • .github/agents/bug-reproduction-validator.agent.md
  • .github/agents/code-simplicity-reviewer.agent.md
  • .github/agents/data-integrity-guardian.agent.md
  • .github/agents/data-migration-expert.agent.md
  • .github/agents/deployment-verification-agent.agent.md
  • .github/agents/design-implementation-reviewer.agent.md
  • .github/agents/design-iterator.agent.md
  • .github/agents/dhh-rails-reviewer.agent.md
  • .github/agents/figma-design-sync.agent.md
  • .github/agents/framework-docs-researcher.agent.md
  • .github/agents/git-history-analyzer.agent.md
  • .github/agents/julik-frontend-races-reviewer.agent.md
  • .github/agents/kieran-python-reviewer.agent.md
  • .github/agents/kieran-rails-reviewer.agent.md
  • .github/agents/kieran-typescript-reviewer.agent.md
  • .github/agents/learnings-researcher.agent.md
  • .github/agents/lint.agent.md
  • .github/agents/pattern-recognition-specialist.agent.md
  • .github/agents/performance-oracle.agent.md
  • .github/agents/pr-comment-resolver.agent.md
  • .github/agents/repo-research-analyst.agent.md
  • .github/agents/schema-drift-detector.agent.md
  • .github/agents/security-sentinel.agent.md
  • .github/agents/spec-flow-analyzer.agent.md
  • .github/skills/.gitignore
  • .github/workflows/check_security_vulnerability.yml
  • .github/workflows/dep.yml
  • .mcp.json
  • .mdformat.toml
  • .tessl/.gitignore
  • AGENTS.md
  • GOTCHAS.md
  • Gemfile
  • app/controllers/agents_controller.rb
  • app/controllers/api/v1/client/health_controller.rb
  • app/controllers/api/v1/client/tasks_controller.rb
  • app/models/ability.rb
  • app/models/agent.rb
  • app/services/task_assignment_service.rb
  • app/views/agents/_capabilities_tab.html.erb
  • app/views/api/v1/client/configuration.json.jbuilder
  • config/configs/application_config.rb
  • config/routes.rb
  • config/routes/client_api.rb
  • docs/README.md
  • docs/api-reference-agent-auth.md
  • spec/requests/api/v1/client/agents_spec.rb
  • spec/requests/api/v1/client/health_spec.rb
  • spec/requests/api/v1/client_spec.rb
  • spec/swagger_helper.rb
  • swagger/v1/swagger.json
  • tessl.json

Comment on lines +3 to +5
tools:
- '*'
infer: true

@coderabbitai coderabbitai Bot Mar 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Restrict this agent’s tool access.

This agent only rewrites README content, but tools: ['*'] gives it every capability and infer: true allows that scope to be granted automatically. Please narrow this to the minimum read/write tools needed for documentation edits so a misfire cannot take unrelated actions.

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 3-3: Multiple headings with the same content

(MD024, no-duplicate-heading)


[warning] 3-3: Multiple headings with the same content

(MD024, no-duplicate-heading)


[warning] 3-3: Multiple headings with the same content

(MD024, no-duplicate-heading)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/agents/ankane-readme-writer.agent.md around lines 3 - 5, The agent's
config currently grants broad tool access via the "tools: '*'" and allows
automatic scope granting with "infer: true"; restrict this by replacing "tools:
'*'" with an explicit minimal list of documentation-related tools (e.g., the
specific read and write tools your platform uses for editing README files) and
set "infer: false" so scopes are not auto-granted; update the keys in
.github/agents/ankane-readme-writer.agent.md (tools and infer) accordingly to
only include the necessary read/write tools for README edits.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

These agent spec files are auto-generated by tessl and managed externally. Changes should be made upstream in the tessl skill definitions, not in these generated files.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@unclesp1d3r, understood — thanks for the context! I'll keep that in mind for future reviews and avoid flagging issues in these externally managed files.


✏️ Learnings added
Learnt from: unclesp1d3r
Repo: unclesp1d3r/CipherSwarm PR: 701
File: .github/agents/ankane-readme-writer.agent.md:3-5
Timestamp: 2026-03-12T16:15:25.979Z
Learning: In the CipherSwarm repository, files under `.github/agents/*.agent.md` (and similar agent spec files) are auto-generated and managed externally by Tessl. Any changes to these files (e.g., tool permissions, infer settings) must be made upstream in the Tessl skill definitions, not directly in the generated files. Do not raise review comments requesting edits to these files.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread .github/agents/ankane-readme-writer.agent.md
- Verify all sentences are 15 words or less
- Ensure all verbs are in imperative form
- Confirm sections appear in the correct order
- Check that all placeholder values (like <gemname>, <user>) are clearly marked

@coderabbitai coderabbitai Bot Mar 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Wrap placeholder tokens in inline code.

Raw <gemname> / <user> placeholders can be treated as HTML in markdown output. Require inline code formatting here so generated README placeholders stay visible.

Proposed fix
-- Check that all placeholder values (like <gemname>, <user>) are clearly marked
+- Check that all placeholder values (like `<gemname>`, `<user>`) are clearly marked
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Check that all placeholder values (like <gemname>, <user>) are clearly marked
- Check that all placeholder values (like `<gemname>`, `<user>`) are clearly marked
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/agents/ankane-readme-writer.agent.md at line 68, Update the README
template guidance to wrap placeholder tokens like <gemname> and <user> in inline
code formatting (e.g., `\<gemname\>`, `\<user\>`) wherever they appear so they
are rendered as literal placeholders instead of being interpreted as HTML;
search for the placeholder occurrences in the ankane-readme-writer agent content
and replace plain occurrences of "<gemname>" and "<user>" with inline-code
versions and ensure any similar tokens follow the same inline code pattern.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

These agent spec files are auto-generated by tessl and managed externally. Changes should be made upstream in the tessl skill definitions, not in these generated files.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@unclesp1d3r, understood! I'll keep that in mind — since these files are auto-generated and managed by Tessl, any content fixes need to go upstream in the Tessl skill definitions rather than being applied directly here.

(˳˘ ɜ˘)˳ ♡


✏️ Learnings added
Learnt from: unclesp1d3r
Repo: unclesp1d3r/CipherSwarm PR: 701
File: .github/agents/ankane-readme-writer.agent.md:68-68
Timestamp: 2026-03-12T16:15:28.746Z
Learning: In the CipherSwarm repository, agent spec files under `.github/agents/` (e.g., `ankane-readme-writer.agent.md`, `architecture-strategist.agent.md`, etc.) are auto-generated and managed externally by Tessl. Changes to their content must be made upstream in the Tessl skill definitions, not directly in these generated files. Do not suggest direct edits to these files in code reviews.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread .github/agents/deployment-verification-agent.agent.md

3. **Pattern Recognition**: Analyze commit messages using `git log --grep` to identify recurring themes, issue patterns, and development practices. Look for keywords like 'fix', 'bug', 'refactor', 'performance', etc.

4. **Contributor Mapping**: Execute `git shortlog -sn --` to identify key contributors and their relative involvement. Cross-reference with specific file changes to map expertise domains.

@coderabbitai coderabbitai Bot Mar 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Scope git shortlog to the files being analyzed.

git shortlog -sn -- reports repository-wide authorship, so it won't support the file-level “expertise domains” mapping this agent is supposed to produce. Pass the target path(s) after --, otherwise the output will be mostly noise on a large repo.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/agents/git-history-analyzer.agent.md at line 36, The current use of
the literal command "git shortlog -sn --" returns repo-wide authorship and must
be scoped to the files being analyzed; change the code that builds the git
command (the invocation that currently uses "git shortlog -sn --") to append the
target path(s) (e.g., a variable like targetPaths or pathsToAnalyze) after the
"--", properly quoting/escaping multiple paths, so the command becomes "git
shortlog -sn -- <paths...>" and handles single or multiple file/path inputs.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

These agent spec files are auto-generated by tessl and managed externally. Changes should be made upstream in the tessl skill definitions, not in these generated files.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@unclesp1d3r, understood — I'll keep that in mind for future reviews and won't flag changes in those generated files.


✏️ Learnings added
Learnt from: unclesp1d3r
Repo: unclesp1d3r/CipherSwarm PR: 701
File: .github/agents/git-history-analyzer.agent.md:36-36
Timestamp: 2026-03-12T16:15:27.008Z
Learning: In the CipherSwarm repository (unclesp1d3r/CipherSwarm), files under `.github/agents/*.agent.md` (and similarly `.github/skills/`, `.claude/skills/`, `.codex/skills/`, `.cursor/skills/`, `.gemini/skills/`) are auto-generated and managed externally by Tessl. Review comments suggesting direct edits to these files are not actionable; any changes must be made upstream in the Tessl skill definitions.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread .github/workflows/dep.yml
Comment thread AGENTS.md
Comment on lines +380 to +385
**View Tests (spec/views/) — planned:**

- Partial rendering tests (e.g., agent configuration tab)
- Use `render partial:` with locals, assert on `rendered`
- Stub `safe_can?` when the partial uses authorization checks

@coderabbitai coderabbitai Bot Mar 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The code block lacks a language specifier, which markdownlint flags as MD040.

📝 Proposed fix
 **View Tests (spec/views/) — planned:**
 
-- Partial rendering tests (e.g., agent configuration tab)
-- Use `render partial:` with locals, assert on `rendered`
-- Stub `safe_can?` when the partial uses authorization checks
+```ruby
+# Example view test structure
+render partial: "agents/configuration_tab", locals: { agent: agent }
+expect(rendered).to have_content("Configuration")
+```
+
+- Stub `safe_can?` when the partial uses authorization checks

Alternatively, if these are meant as bullet points rather than code, ensure the formatting is consistent.

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 383-383: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` around lines 380 - 385, The fenced code block around the example
view test is missing a language specifier (MD040); update the block so the
opening fence is "```ruby" and ensure it closes with "```" so the snippet (e.g.,
render partial: "agents/configuration_tab", locals: { agent: agent } /
expect(rendered).to have_content("Configuration")) is treated as Ruby, or
alternatively convert the snippet into consistent bullet points if it was not
intended as code; also ensure the note about stubbing safe_can? remains
formatted consistently with the chosen style.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

False positive — these are bullet points, not a fenced code block. There is no unlabeled code fence in this section of AGENTS.md.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@unclesp1d3r, you're right — I apologize for the false positive. Looking at the diff again, those are plain bullet points using inline code backticks (single backticks around render partial: and rendered), not a fenced code block. There is no unlabeled triple-backtick fence in this section, so the MD040 warning doesn't apply here. The markdownlint tool appears to have incorrectly flagged the inline backtick within the bullet point.

Comment thread docs/api-reference-agent-auth.md
Comment thread docs/api-reference-agent-auth.md
Comment thread docs/api-reference-agent-auth.md Outdated
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Comment thread tessl.json Dismissed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tessl.json (1)

5-9: Reduce secret-scanner noise for the pinned SHAs.

These values look like intentional commit pins, but they will keep tripping generic secret detectors. Please add an allowlist/suppression for this manifest or these fields in the same PR so real secret findings do not get buried in repeat noise.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tessl.json` around lines 5 - 9, These pinned commit SHAs in tessl.json (the
"version" fields such as under "getsentry/skills") are intentional and causing
secret-scanner noise; add a suppression/allowlist for this manifest and/or these
specific JSON fields in the same PR so scanners ignore them—specifically update
the secret-scanner config to whitelist the file name tessl.json and the JSON key
"version" (or add a fingerprint/regex matching the pinned SHA format for these
entries) and include a short justification comment for the suppression so future
reviewers understand it is intentional.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tessl.json`:
- Around line 5-9: These pinned commit SHAs in tessl.json (the "version" fields
such as under "getsentry/skills") are intentional and causing secret-scanner
noise; add a suppression/allowlist for this manifest and/or these specific JSON
fields in the same PR so scanners ignore them—specifically update the
secret-scanner config to whitelist the file name tessl.json and the JSON key
"version" (or add a fingerprint/regex matching the pinned SHA format for these
entries) and include a short justification comment for the suppression so future
reviewers understand it is intentional.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eb25c040-b7db-4bc0-9173-f4ba82c934f3

📥 Commits

Reviewing files that changed from the base of the PR and between 7fbd76b and 405d160.

📒 Files selected for processing (1)
  • tessl.json

@mergify

mergify Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

🧪 CI Insights

Here's what we observed from your CI run for 2039a33.

🟢 All jobs passed!

But CI Insights is watching 👀

…nd auto-activation

Adds tests to satisfy undercover coverage requirements:
- agents_spec: expire_benchmarks authorization and functionality
- health_spec: database failure returns degraded status
- tasks_spec: activate_pending_agent_with_benchmarks branch coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Copilot AI review requested due to automatic review settings March 12, 2026 15:51
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Comment thread tessl.json Dismissed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
spec/requests/api/v1/client/tasks_spec.rb (1)

1044-1056: Consider verifying agent state when activation fails.

The test verifies that the activation log is not emitted when activate returns false, but doesn't confirm the agent remains in the pending state. Adding this assertion would strengthen the test.

♻️ Optional: Add state verification
     context "when activate fails" do
       it "does not log activation" do
         pending_agent = create(:agent, state: "pending")
         create(:hashcat_benchmark, agent: pending_agent)
         allow(Rails.logger).to receive(:info)
         allow_any_instance_of(Agent).to receive(:activate).and_return(false) # rubocop:disable RSpec/AnyInstance
 
         get "/api/v1/client/tasks/new",
             headers: { "Authorization" => "Bearer #{pending_agent.token}" }
 
+        pending_agent.reload
+        expect(pending_agent.state).to eq("pending")
         expect(Rails.logger).not_to have_received(:info).with(/\[AgentLifecycle\] auto_activate/)
       end
     end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spec/requests/api/v1/client/tasks_spec.rb` around lines 1044 - 1056, The test
should also assert the agent's state didn't change when activation fails: after
issuing the GET request, reload the pending_agent and add an expectation that
pending_agent.reload.state == "pending" (reference: the pending_agent
factory/variable and Agent#activate method) to ensure the record remains in the
pending state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@spec/requests/api/v1/client/tasks_spec.rb`:
- Around line 1044-1056: The test should also assert the agent's state didn't
change when activation fails: after issuing the GET request, reload the
pending_agent and add an expectation that pending_agent.reload.state ==
"pending" (reference: the pending_agent factory/variable and Agent#activate
method) to ensure the record remains in the pending state.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d6d32b53-d307-42b6-a923-bd94666dbe76

📥 Commits

Reviewing files that changed from the base of the PR and between 405d160 and ff22c5b.

📒 Files selected for processing (4)
  • spec/requests/agents_spec.rb
  • spec/requests/api/v1/client/health_spec.rb
  • spec/requests/api/v1/client/tasks_spec.rb
  • tessl.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • spec/requests/api/v1/client/health_spec.rb

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 66 out of 67 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +316 to +323
scope = Attack.incomplete
.joins(campaign: { hash_list: :hash_type })
.includes(campaign: %i[hash_list project])
.where(hash_lists: { hash_type_id: allowed_hash_type_ids })

scope = scope.where(campaigns: { project_id: agent.project_ids }) if agent.project_ids.present?

scope.order("campaigns.priority DESC, attacks.complexity_value, attacks.created_at")

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

Same multi-tenancy concern as above: when agent.project_ids is blank, available_attacks becomes effectively unscoped by project and may hand the agent work from campaigns in projects it should not access. If “no project assignments” is intended to mean “all projects the owning user can access”, scope to that set explicitly; otherwise keep the project filter mandatory.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

This is by design — agents with no project assignments are intentionally allowed to work on any project, matching the convention used by attack resources (word lists, rule lists, mask lists) and Task#compatible_agent?. See AGENTS.md under "Agent Task Assignment".

Comment on lines 304 to +308
# Returns attacks available for the agent based on projects and hash types.
#
# Agents with no project assignments can work on any project (same convention
# as attack resources like word lists, rule lists, and Task#agent_compatible?).
#

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

The inline documentation references Task#agent_compatible?, but there doesn’t appear to be any such method in the codebase. This makes the comment misleading for future maintainers; either update it to reference the actual compatibility logic/policy, or remove the reference.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in this push — corrected to Task#compatible_agent?.

Comment on lines +19 to +27
response(200, "healthy") do
schema type: :object,
properties: {
status: { type: :string, description: "Overall health status (ok or degraded)" },
api_version: { type: :integer, description: "API version" },
timestamp: { type: :string, format: "date-time", description: "Server timestamp" },
database: { type: :string, description: "Database health (healthy or unhealthy)" }
},
required: %i[status api_version timestamp database]

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

This rswag spec (and the generated swagger/v1/swagger.json) documents only a 200 response, but the controller returns 503 Service Unavailable with {status:"degraded", database:"unhealthy"} when the DB check fails. Add a response(503, ...) block (with schema + example) so the OpenAPI accurately reflects runtime behavior, then regenerate the swagger JSON.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in this push — added response(503, "degraded") rswag test case.

Comment on lines +45 to +51
<% if safe_can?(:expire_benchmarks, agent) %>
<%= button_to "Expire Benchmarks",
expire_benchmarks_agent_path(agent),
method: :post,
class: "btn btn-outline-warning btn-sm",
data: { turbo_confirm: "This will delete all benchmarks and force the agent to re-benchmark on its next check-in. Continue?" } %>
<% end %>

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

safe_can? is evaluated when this partial is rendered in Turbo Stream broadcasts (see Agent#broadcast_tab_updates), where there is no current_user/Warden context. In that environment safe_can? returns false, so the broadcasted update will remove the “Expire Benchmarks” button for all viewers, even if they’re authorized. Authorization-gated UI elements shouldn’t live inside broadcast-rendered partials; move the button outside the broadcasted fragment (or update only the benchmark table via broadcasts) and rely on controller authorization for enforcement.

Copilot uses AI. Check for mistakes.
Comment on lines +141 to +146
.joins(attack: { campaign: :hash_list })
.where(hash_lists: { hash_type_id: allowed_hash_type_ids })

scope = scope.where(campaigns: { project_id: agent.project_ids }) if agent.project_ids.present?

task = scope

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

When agent.project_ids is blank, this now omits any campaigns.project_id scoping, meaning an agent with no project assignments can claim paused tasks from any project. Given the app’s project-based multi-tenancy, this is a cross-tenant access risk. Consider scoping to the agent’s user-accessible projects (e.g., agent.user.all_project_ids) or requiring explicit project assignment before allowing task pickup.

Copilot uses AI. Check for mistakes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (6)
docs/user-guide/troubleshooting-agents.md (6)

825-862: Fix protocol inconsistency and add language specifier.

The curl examples use http:// (lines 830, 860, 888) while other sections use https://. For security best practices, consider:

  1. Using https:// consistently for production examples
  2. Adding a note if http:// is intentional for local/development environments

Also, the bash code block at line 828 should specify bash as the language for syntax highlighting.

🔒 Proposed fix for security and consistency
-   ```bash
+   ```bash
    # This endpoint does not require authentication
-   curl -v http://your-server/api/v1/client/health
+   curl -v https://your-server/api/v1/client/health
    ```
 
    **Expected response (healthy server)**:

Apply similar changes to other curl examples in this section (lines 860, 888).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/user-guide/troubleshooting-agents.md` around lines 825 - 862, Update the
curl examples under the "Test server health endpoint" and the "Verify resilience
configuration is being fetched" code blocks to use https:// instead of http://
for production-safe examples, and add a brief parenthetical note stating that
http:// may be used for local development only; also mark the first bash code
fence with a language specifier (```bash) so the health-check block is
highlighted correctly — locate these changes in the code blocks that contain the
curl commands for /api/v1/client/health and /api/v1/client/configuration in the
"Test server health endpoint" and subsequent verification steps.

205-211: Add language specifiers to code blocks and consider protocol consistency.

  1. The bash code block at line 205 should specify bash as the language for proper syntax highlighting. As per static analysis hints, fenced code blocks should have a language specified.

  2. The health endpoint example uses http:// (line 206) while the authentication example uses https:// (line 209). Consider using consistent protocols or adding a comment explaining when to use HTTP vs HTTPS to avoid user confusion.

📝 Proposed fix
-   ```
+   ```bash
    # Test health endpoint (unauthenticated)
-   curl -v http://server.example.com/api/v1/client/health
+   curl -v https://server.example.com/api/v1/client/health
 
    # Test authentication
    curl -H "Authorization: Bearer <token>" \
      https://server.example.com/api/v1/client/authenticate
    ```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/user-guide/troubleshooting-agents.md` around lines 205 - 211, Add a
language specifier ("bash") to the fenced code block containing the curl
examples and make the protocol consistent: update the health-check curl line
("curl -v http://server.example.com/api/v1/client/health") to use https to match
the authenticate example ("curl -H \"Authorization: Bearer <token>\"
https://server.example.com/api/v1/client/authenticate"), or alternatively add a
brief inline comment before the two curl lines explaining when to use http vs
https.

1119-1127: Ensure consistency with earlier health endpoint examples.

This section duplicates the health endpoint check pattern from lines 205-211. For consistency:

  1. Add bash language specifier to the code block (line 1121)
  2. Consider using https:// instead of http:// for production examples (line 1123)
  3. The "Alternative" label (line 1125) is a nice touch that could be backported to the earlier example at line 208 for consistency
📝 Proposed fix for consistency
    ```bash
    # Check health endpoint (no authentication required)
-   curl -v http://server.example.com/api/v1/client/health
+   curl -v https://server.example.com/api/v1/client/health
 
    # Alternative: check authenticated endpoint
    curl -I https://server.example.com/api/v1/client/authenticate
    ```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/user-guide/troubleshooting-agents.md` around lines 1119 - 1127, Update
the health-check code block to match earlier examples: add the bash code-fence
language specifier, change the health endpoint URL in the curl command from
http:// to https://, and preserve the "Alternative: check authenticated
endpoint" label and its curl -I https://... line; also mirror this "Alternative"
label and formatting in the earlier health-check example so both examples are
consistent (look for the health endpoint check code blocks / health endpoint
curl examples to apply these edits).

911-928: Add language specifier to YAML code block.

The YAML configuration example at lines 915-926 is missing a language specifier. As per static analysis hints, fenced code blocks should specify their language for proper syntax highlighting and validation.

📝 Proposed fix
 Server operators can tune resilience parameters without redeploying agents by modifying the application configuration:
 
-```yaml
+```yaml
 # config/application.yml (example)
 recommended_connect_timeout: 10      # seconds
 recommended_read_timeout: 30         # seconds
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/user-guide/troubleshooting-agents.md` around lines 911 - 928, The fenced
code block showing the server-side configuration is missing a language
specifier; update the Markdown block that contains the YAML keys (e.g.,
recommended_connect_timeout, recommended_read_timeout,
recommended_write_timeout, etc.) to start with ```yaml so the block becomes a
YAML-annotated fence for proper highlighting and linting.

385-393: Add language specifiers to fenced code elements.

The inline code references at lines 390-391 appear to be list items, not fenced code blocks. However, if these were intended as code blocks, they should specify a language. The static analysis tool flagged these lines - please verify the intended formatting.

If the intent is to show individual configuration keys as inline code within bullet points, the current markdown is correct. If these should be formatted as a code block showing the structure, consider:

📝 Alternative formatting
 These parameters allow server operators to tune agent behavior without redeploying agent software. Agents should apply these values when first connecting and refresh them periodically (e.g., every 24 hours) by re-fetching the configuration endpoint. See the [Client Resilience Recommendations](../api-reference-agent-auth.md#client-resilience-recommendations) section of the API reference for implementation details.
-

Or keep as-is if the list format is preferred. The static analysis warning may be a false positive.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/user-guide/troubleshooting-agents.md` around lines 385 - 393, Verify
whether the four timeout keys (connect_timeout, read_timeout, write_timeout,
request_timeout) and the retry/circuit-breaker keys (max_attempts,
initial_delay, max_delay, failure_threshold, timeout) were intended as inline
code in the bullet list or as a fenced code block; if inline is intended, leave
the bullets as-is, otherwise replace the bullets with a single fenced code block
(specify a language such as yaml or json) showing the configuration structure
containing those keys so the static analysis tool warning is resolved and the
examples are properly syntax-highlighted.

815-824: Consider clarifying agent implementation requirements.

The diagnostic steps provide clear guidance, but line 822-823 suggests checking for specific agent features:

cipherswarm-agent --version
cipherswarm-agent --features

These commands assume a specific agent CLI interface. Since agents can be implemented in various languages (the PR context mentions Go clients), consider adding a note that these are example commands and agents should consult their specific documentation for version/feature checking.

📝 Proposed clarification
 1. **Check if agent supports resilience features**:
 
    ```bash
-   # Check agent version and features
+   # Check agent version and features (commands vary by agent implementation)
    cipherswarm-agent --version
    cipherswarm-agent --features
    ```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/user-guide/troubleshooting-agents.md` around lines 815 - 824, Update the
diagnostic step that shows the CLI commands "cipherswarm-agent --version" and
"cipherswarm-agent --features" to make clear these are example commands and may
differ across agent implementations (e.g., Go clients or other language-specific
CLIs); modify the text around those symbols to read something like "Check agent
version and features (commands vary by agent implementation)" and add a short
note telling readers to consult their agent's documentation for the exact
commands.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@docs/user-guide/troubleshooting-agents.md`:
- Around line 825-862: Update the curl examples under the "Test server health
endpoint" and the "Verify resilience configuration is being fetched" code blocks
to use https:// instead of http:// for production-safe examples, and add a brief
parenthetical note stating that http:// may be used for local development only;
also mark the first bash code fence with a language specifier (```bash) so the
health-check block is highlighted correctly — locate these changes in the code
blocks that contain the curl commands for /api/v1/client/health and
/api/v1/client/configuration in the "Test server health endpoint" and subsequent
verification steps.
- Around line 205-211: Add a language specifier ("bash") to the fenced code
block containing the curl examples and make the protocol consistent: update the
health-check curl line ("curl -v
http://server.example.com/api/v1/client/health") to use https to match the
authenticate example ("curl -H \"Authorization: Bearer <token>\"
https://server.example.com/api/v1/client/authenticate"), or alternatively add a
brief inline comment before the two curl lines explaining when to use http vs
https.
- Around line 1119-1127: Update the health-check code block to match earlier
examples: add the bash code-fence language specifier, change the health endpoint
URL in the curl command from http:// to https://, and preserve the "Alternative:
check authenticated endpoint" label and its curl -I https://... line; also
mirror this "Alternative" label and formatting in the earlier health-check
example so both examples are consistent (look for the health endpoint check code
blocks / health endpoint curl examples to apply these edits).
- Around line 911-928: The fenced code block showing the server-side
configuration is missing a language specifier; update the Markdown block that
contains the YAML keys (e.g., recommended_connect_timeout,
recommended_read_timeout, recommended_write_timeout, etc.) to start with ```yaml
so the block becomes a YAML-annotated fence for proper highlighting and linting.
- Around line 385-393: Verify whether the four timeout keys (connect_timeout,
read_timeout, write_timeout, request_timeout) and the retry/circuit-breaker keys
(max_attempts, initial_delay, max_delay, failure_threshold, timeout) were
intended as inline code in the bullet list or as a fenced code block; if inline
is intended, leave the bullets as-is, otherwise replace the bullets with a
single fenced code block (specify a language such as yaml or json) showing the
configuration structure containing those keys so the static analysis tool
warning is resolved and the examples are properly syntax-highlighted.
- Around line 815-824: Update the diagnostic step that shows the CLI commands
"cipherswarm-agent --version" and "cipherswarm-agent --features" to make clear
these are example commands and may differ across agent implementations (e.g., Go
clients or other language-specific CLIs); modify the text around those symbols
to read something like "Check agent version and features (commands vary by agent
implementation)" and add a short note telling readers to consult their agent's
documentation for the exact commands.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee61d3fd-c677-4861-b919-f3c2096bd219

📥 Commits

Reviewing files that changed from the base of the PR and between ff22c5b and 2b74f5a.

📒 Files selected for processing (1)
  • docs/user-guide/troubleshooting-agents.md

- Add user_id to CONFIGURATION_BROADCAST_FIELDS for admin reassignment
- Fix capabilities broadcast indentation in agent.rb
- Collapse exists?+count into single count query in tasks_controller
- Fix stale method reference (agent_compatible? → compatible_agent?)
- Fix incorrect SystemHealthCheckService reference in health_controller
- Add pull-requests: write permission to dep.yml for comment-summary
- Add health check section and idempotency warning to API reference
- Add 503 degraded response to health_spec and regenerate swagger.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Copilot AI review requested due to automatic review settings March 12, 2026 16:20
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 67 out of 68 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread swagger/v1/swagger.json
Comment on lines +94 to +114
"ErrorMetadata": {
"type": "object",
"nullable": true,
"description": "Additional metadata about an agent error",
"properties": {
"error_date": {
"type": "string",
"format": "date-time",
"description": "The date of the error"
},
"other": {
"type": "object",
"nullable": true,
"description": "Other metadata",
"additionalProperties": true
}
},
"required": [
"error_date"
]
},

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

ErrorMetadata is defined with only error_date and other, and does not allow additional top-level keys. However the API currently accepts/stores arbitrary metadata keys at the top level (e.g., metadata: { error_date: ..., key: "value" } in request specs; controller also adds metadata[:additional_info]). This makes the OpenAPI contract inaccurate and (with openapi_no_additional_properties / openapi_all_properties_required) would force clients to send/receive fields the server doesn’t actually structure that way. Either update the schema to allow arbitrary top-level keys (e.g., additionalProperties: true alongside error_date), or standardize the API to nest arbitrary fields under other and always include other (nullable) when metadata is present.

Copilot uses AI. Check for mistakes.
Comment thread spec/swagger_helper.rb
Comment on lines +101 to +110
ErrorMetadata: {
type: :object,
nullable: true,
description: "Additional metadata about an agent error",
properties: {
error_date: { type: :string, format: "date-time", description: "The date of the error" },
other: { type: :object, nullable: true, description: "Other metadata", additionalProperties: true }
},
required: %i[error_date]
},

Copilot AI Mar 12, 2026

Copy link

Choose a reason for hiding this comment

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

The ErrorMetadata schema here doesn’t match actual submit_error behavior/tests: metadata is treated as a free-form hash with top-level keys (and the controller adds keys like :additional_info). With openapi_no_additional_properties=true and openapi_all_properties_required=true, declaring other but not allowing additional top-level keys (or always returning other) will make schema validation/documentation misleading. Align the schema with the real payload shape (either allow additionalProperties: true at the root, or enforce { error_date, other } in the API and always include other).

Copilot uses AI. Check for mistakes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
swagger/v1/swagger.json (1)

3-16: ⚠️ Potential issue | 🔴 Critical

Scope SDK retries to safe operations only.

The root-level x-speakeasy-retries policy is inherited by every operation generated in the SDK, including non-idempotent POST operations like accept_task, submit_crack, and submit_error. This creates a critical risk: retries can duplicate side effects if the server commits the write but the client loses the response.

To fix this, remove the global policy and instead add x-speakeasy-retries only to idempotent operations (e.g., GET, HEAD), or if retries are needed on POST operations, ensure each defines an idempotency header so the same key is reused on retry.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@swagger/v1/swagger.json` around lines 3 - 16, The global x-speakeasy-retries
policy at the root should be removed and applied only to safe/idempotent
operations: delete the root-level "x-speakeasy-retries" block and add an
"x-speakeasy-retries" object to individual idempotent operations (e.g., all GET
and HEAD operation objects) instead; for any POST operations that must retry,
modify those operation objects (for example "accept_task", "submit_crack",
"submit_error") to either omit retries or add an explicit idempotency header
contract so retries reuse the same idempotency key. Ensure you update the
swagger JSON by removing the top-level x-speakeasy-retries and adding the same
backoff/statusCodes/retryConnectionErrors fields only under the operation
objects that should retry (or replace with an idempotency header definition for
POSTs).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/services/task_assignment_service.rb`:
- Around line 306-323: Add a REASONING comment block immediately before the
available_attacks method explaining: intent (why we extracted this logic into
TaskAssignmentService), alternatives considered (e.g., keeping logic on Task
model or controller), decision rationale (consistency with
Task#compatible_agent? and find_unassigned_paused_task, readability,
testability), performance implications (DB joins, indexes, and filtering by
allowed_hash_type_ids / project_ids), and future considerations (caching,
pagination, and potential edge cases). Keep the block concise, use clear
headings for each section, and reference the method name available_attacks and
related behaviors (Task#compatible_agent?, find_unassigned_paused_task) so
reviewers can see the linkage.

In `@docs/api-reference-agent-auth.md`:
- Around line 631-635: The pseudocode for retry jitter uses delay on the
right-hand side before it's defined; change it to compute a base_delay first as
base_delay = min(initial_delay * 2^attempt, max_delay) and then compute delay
from that base as delay = base_delay + random(0, base_delay * 0.5), replacing
the old single-line expression that referenced delay on the right-hand side;
ensure the symbols initial_delay, attempt, max_delay, base_delay, and delay are
used exactly as shown.

In `@swagger/v1/swagger.json`:
- Around line 1295-1318: Update the health endpoint response schemas so the 200
and 503 responses use explicit enum values instead of free-form strings: for the
200 response schema (where "status" and "database" are currently defined) change
"status" to an enum with only "ok" and "database" to an enum with only
"healthy"; for the 503 response schema change "status" to an enum with only
"degraded" and "database" to an enum with only "unhealthy". Locate and modify
the JSON objects that define the response schemas for HTTP 200 and 503 (the
properties "status" and "database" in the health response definitions) to use
"enum" arrays with those specific values and keep other fields (api_version,
timestamp) unchanged.

---

Outside diff comments:
In `@swagger/v1/swagger.json`:
- Around line 3-16: The global x-speakeasy-retries policy at the root should be
removed and applied only to safe/idempotent operations: delete the root-level
"x-speakeasy-retries" block and add an "x-speakeasy-retries" object to
individual idempotent operations (e.g., all GET and HEAD operation objects)
instead; for any POST operations that must retry, modify those operation objects
(for example "accept_task", "submit_crack", "submit_error") to either omit
retries or add an explicit idempotency header contract so retries reuse the same
idempotency key. Ensure you update the swagger JSON by removing the top-level
x-speakeasy-retries and adding the same
backoff/statusCodes/retryConnectionErrors fields only under the operation
objects that should retry (or replace with an idempotency header definition for
POSTs).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b115979b-118d-4ea0-8ff6-422848eb9a50

📥 Commits

Reviewing files that changed from the base of the PR and between 2b74f5a and 747c33e.

📒 Files selected for processing (8)
  • .github/workflows/dep.yml
  • app/controllers/api/v1/client/health_controller.rb
  • app/controllers/api/v1/client/tasks_controller.rb
  • app/models/agent.rb
  • app/services/task_assignment_service.rb
  • docs/api-reference-agent-auth.md
  • spec/requests/api/v1/client/health_spec.rb
  • swagger/v1/swagger.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • spec/requests/api/v1/client/health_spec.rb
  • app/controllers/api/v1/client/health_controller.rb
  • .github/workflows/dep.yml

Comment on lines +306 to +323
# Agents with no project assignments can work on any project (same convention
# as attack resources like word lists, rule lists, and Task#compatible_agent?).
#
# Ordering strategy:
# 1. campaigns.priority DESC: Higher campaign priority first (high=2, normal=0, deferred=-1)
# 2. attacks.complexity_value: Within same priority, simpler attacks first
# 3. attacks.created_at: Tie-breaker for same priority and complexity
#
# @return [ActiveRecord::Relation<Attack>] attacks ordered by campaign priority, complexity, creation time
def available_attacks
Attack.incomplete
.joins(campaign: { hash_list: :hash_type })
.includes(campaign: %i[hash_list project])
.where(campaigns: { project_id: agent.project_ids })
.where(hash_lists: { hash_type_id: allowed_hash_type_ids })
.order("campaigns.priority DESC, attacks.complexity_value, attacks.created_at")
scope = Attack.incomplete
.joins(campaign: { hash_list: :hash_type })
.includes(campaign: %i[hash_list project])
.where(hash_lists: { hash_type_id: allowed_hash_type_ids })

scope = scope.where(campaigns: { project_id: agent.project_ids }) if agent.project_ids.present?

scope.order("campaigns.priority DESC, attacks.complexity_value, attacks.created_at")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify Task#compatible_agent? follows the same project filtering convention

# Search for the compatible_agent? method implementation
ast-grep --pattern $'def compatible_agent?($$$)
  $$$
end'

# Also search for project-related filtering in Task model
rg -n -C5 'project_ids' --type ruby -g 'app/models/task.rb'

Repository: unclesp1d3r/CipherSwarm

Length of output: 376


Add REASONING block to document method extraction and design decisions.

The refactored available_attacks method correctly implements the same project-filtering convention as Task#compatible_agent?: agents without project assignments can work on any project. The conditional filtering pattern matches find_unassigned_paused_task, and the ordering strategy is preserved.

However, per coding guidelines, all service objects require a formal REASONING block explaining why this extraction was made, alternatives considered, decision rationale, performance implications, and future considerations. The current comment documents the ordering strategy and convention but lacks the required REASONING structure.

Add a REASONING comment block before the method definition with the required sections.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/services/task_assignment_service.rb` around lines 306 - 323, Add a
REASONING comment block immediately before the available_attacks method
explaining: intent (why we extracted this logic into TaskAssignmentService),
alternatives considered (e.g., keeping logic on Task model or controller),
decision rationale (consistency with Task#compatible_agent? and
find_unassigned_paused_task, readability, testability), performance implications
(DB joins, indexes, and filtering by allowed_hash_type_ids / project_ids), and
future considerations (caching, pagination, and potential edge cases). Keep the
block concise, use clear headings for each section, and reference the method
name available_attacks and related behaviors (Task#compatible_agent?,
find_unassigned_paused_task) so reviewers can see the linkage.

Comment on lines +631 to +635
Use exponential backoff with the `recommended_retry` parameters:

```text
delay = min(initial_delay * 2^attempt, max_delay) + random(0, delay * 0.5)
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix the retry jitter pseudocode.

The expression uses delay on the right-hand side before it exists, so clients copying this literally cannot compute the jitter bound.

✏️ Suggested fix
-```text
-delay = min(initial_delay * 2^attempt, max_delay) + random(0, delay * 0.5)
-```
+```text
+base_delay = min(initial_delay * 2^attempt, max_delay)
+delay = base_delay + random(0, base_delay * 0.5)
+```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/api-reference-agent-auth.md` around lines 631 - 635, The pseudocode for
retry jitter uses delay on the right-hand side before it's defined; change it to
compute a base_delay first as base_delay = min(initial_delay * 2^attempt,
max_delay) and then compute delay from that base as delay = base_delay +
random(0, base_delay * 0.5), replacing the old single-line expression that
referenced delay on the right-hand side; ensure the symbols initial_delay,
attempt, max_delay, base_delay, and delay are used exactly as shown.

Comment thread swagger/v1/swagger.json
Comment on lines +1295 to +1318
"status": {
"type": "string",
"description": "Overall health status (ok or degraded)"
},
"api_version": {
"type": "integer",
"description": "API version"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "Server timestamp"
},
"database": {
"type": "string",
"description": "Database health (healthy or unhealthy)"
}
},
"required": [
"status",
"api_version",
"timestamp",
"database"
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Tighten the health response contract.

Both responses currently accept any string, and the 200 schema even describes degraded as valid. Pin the 200 response to status: "ok" / database: "healthy" and the 503 response to status: "degraded" / database: "unhealthy" so generated clients can branch on stable enums instead of free-form text.

Also applies to: 1330-1353

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@swagger/v1/swagger.json` around lines 1295 - 1318, Update the health endpoint
response schemas so the 200 and 503 responses use explicit enum values instead
of free-form strings: for the 200 response schema (where "status" and "database"
are currently defined) change "status" to an enum with only "ok" and "database"
to an enum with only "healthy"; for the 503 response schema change "status" to
an enum with only "degraded" and "database" to an enum with only "unhealthy".
Locate and modify the JSON objects that define the response schemas for HTTP 200
and 503 (the properties "status" and "database" in the health response
definitions) to use "enum" arrays with those specific values and keep other
fields (api_version, timestamp) unchanged.

@unclesp1d3r

Copy link
Copy Markdown
Owner Author

@Mergifyio queue

@mergify

mergify Bot commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

This pull request spent 10 seconds in the queue, including 1 second running CI.

Required conditions to merge

Reason

Pull request #701 has been dequeued, merge conditions unmatch:

  • check-success = DCO
  • check-success = lint
  • check-success = lint_api
  • check-success = scan_ruby
  • check-success = test
  • all of [🛡 Merge Protections rule CI must pass]:
    • check-success = DCO
    • check-success = lint
    • check-success = lint_api
    • check-success = scan_ruby
    • check-success = test
  • any of:
    • author = dependabot[bot]
    • label = lgtm
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-neutral = Mergify Merge Protections
    • check-skipped = Mergify Merge Protections
    • check-success = Mergify Merge Protections
  • all of [🛡 Merge Protections rule Do not merge outdated PRs]:
    • #commits-behind <= 10
  • all of [🛡 Merge Protections rule Enforce conventional commit]:
    • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?:

Hint

You should look at the reason for the failure and decide if the pull request needs to be fixed or if you want to requeue it.
If you do update this pull request, it will automatically be requeued once the queue conditions match again.
If you think this was a flaky issue instead, you can requeue the pull request, without updating it, by posting a @mergifyio queue comment.

@mergify mergify Bot added the queued label Mar 13, 2026
mergify Bot added a commit that referenced this pull request Mar 13, 2026
@mergify mergify Bot added dequeued and removed queued labels Mar 13, 2026
@unclesp1d3r unclesp1d3r merged commit 512d2da into main Mar 13, 2026
15 of 16 checks passed
@unclesp1d3r unclesp1d3r deleted the 464-agent-clients-lack-timeout-and-retry-logic-hang-indefinitely-when-server-is-unresponsive branch March 13, 2026 07:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent management and monitoring dequeued size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent clients lack timeout and retry logic, hang indefinitely when server is unresponsive

3 participants