Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .fullsend/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ version: "1"
# directories before every run. Keep repo-owned agents under rhdh/ so their
# harnesses and resources remain intact.
agents:
- name: triage
source: rhdh/harness/triage-jira.yaml
- name: code
source: rhdh/harness/code.yaml
- name: fix
Expand All @@ -24,7 +26,7 @@ roles:
allowed_remote_resources:
- https://raw.githubusercontent.com/fullsend-ai/fullsend/
- https://raw.githubusercontent.com/fullsend-ai/agents/
- https://github.com/redhat-developer/rhdh-skill/
- https://github.com/redhat-developer/rhdh-skills/
create_issues:
allow_targets:
repos:
Expand Down
22 changes: 14 additions & 8 deletions .fullsend/rhdh/agents/code.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: code
description: >-
Implementation specialist for GitHub issues. Reads triaged issues, implements
fixes following repo conventions, runs tests and linters, and commits to a
feature branch. Use when implementing a fix or feature from a triaged issue.
Implementation specialist for GitHub or Jira issues. Reads triaged issues,
implements fixes following repo conventions, runs tests and linters, and
commits to a feature branch. Use when implementing a fix or feature from a
triaged issue.
model: opus
skills:
- code-implementation
Expand All @@ -12,11 +13,11 @@ skills:
# Code Agent

You are an implementation specialist. Your purpose is to read a triaged GitHub
issue, implement a fix or feature following the target repository's conventions,
verify it passes tests and linters, and commit the result to a local feature
branch. You do not triage issues, review PRs, push branches, create PRs, or
merge code — you implement and commit. A deterministic automation layer handles
pushing and PR creation after you finish.
issue or Jira work item, implement a fix or feature following the target
repository's conventions, verify it passes tests and linters, and commit the
result to a local feature branch. You do not triage issues, review PRs, push
branches, create PRs, or merge code — you implement and commit. A deterministic
automation layer handles pushing and PR creation after you finish.

## Identity

Expand All @@ -26,6 +27,11 @@ Before writing any code, you must be able to answer three questions:
2. **Why does it happen?** (Verified against the code, not assumed from the issue.)
3. **What is the smallest correct change?**

When `FULLSEND_TRACKER=jira`, use `ISSUE_URL` and the Jira API credentials
provided by the harness to read the work item and its comments. Stop if the
work item cannot be read. Never infer Jira ticket details from a similarly
named GitHub issue.

You implement changes across five phases:

1. **Context gathering** — read the issue, triage output, linked context, and
Expand Down
17 changes: 15 additions & 2 deletions .fullsend/rhdh/harness/code.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,26 @@ image: ghcr.io/redhat-developer/rhdh-fullsend-code:latest
# profiles/fullsend-vertex-ai.yaml now does that upstream (ADR 0065's
# provider/profile network policy migration).
skills:
- https://github.com/redhat-developer/rhdh-skill/tree/e84109919ae6085e3dcfe568c695e6dda54874ce/skills/rhdh-coding#sha256=5a4bc35476108a215091ccf1180cee68547c7668c6b193de4402674bc7b6cded
- https://github.com/redhat-developer/rhdh-skills/tree/e84109919ae6085e3dcfe568c695e6dda54874ce/skills/rhdh-coding#sha256=5a4bc35476108a215091ccf1180cee68547c7668c6b193de4402674bc7b6cded
# Harness-level allowlist required for URL skills (not inherited from base or
# config.yaml). Must also be covered by config.yaml allowed_remote_resources.
allowed_remote_resources:
- https://github.com/redhat-developer/rhdh-skill/
- https://github.com/redhat-developer/rhdh-skills/
host_files:
- src: rhdh/bin/yarn
dest: /sandbox/workspace/bin/yarn
- src: rhdh/env/yarn-proxy.env
dest: /sandbox/workspace/.env.d/yarn-proxy.env
# A Jira work item has no GitHub issue number. Keep generated PRs on main.
env:
runner:
CODE_ALLOWED_TARGET_BRANCHES: "main"

# The Jira poller evaluates explicit CEL triggers. GitHub /fs-code continues
# to use Fullsend's built-in stage router.
trigger: >
event.source.system == "jira"
&& event.transition.kind == "comment_added"
&& has(event.transition.comment.command)
&& event.transition.comment.command == "/fs-code"
&& event.entity.kind == "work_item"
4 changes: 2 additions & 2 deletions .fullsend/rhdh/harness/fix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ image: ghcr.io/redhat-developer/rhdh-fullsend-code:latest
# profiles/fullsend-vertex-ai.yaml now does that upstream (ADR 0065's
# provider/profile network policy migration).
skills:
- https://github.com/redhat-developer/rhdh-skill/tree/e84109919ae6085e3dcfe568c695e6dda54874ce/skills/rhdh-coding#sha256=5a4bc35476108a215091ccf1180cee68547c7668c6b193de4402674bc7b6cded
- https://github.com/redhat-developer/rhdh-skills/tree/e84109919ae6085e3dcfe568c695e6dda54874ce/skills/rhdh-coding#sha256=5a4bc35476108a215091ccf1180cee68547c7668c6b193de4402674bc7b6cded
# Harness-level allowlist required for URL skills (not inherited from base or
# config.yaml). Must also be covered by config.yaml allowed_remote_resources.
allowed_remote_resources:
- https://github.com/redhat-developer/rhdh-skill/
- https://github.com/redhat-developer/rhdh-skills/
host_files:
- src: rhdh/bin/yarn
dest: /sandbox/workspace/bin/yarn
Expand Down
18 changes: 18 additions & 0 deletions .fullsend/rhdh/harness/triage-jira.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# The stock triage harness has no CEL trigger. Jira polling needs an explicit
# trigger so /fs-triage comments are routed to the triage agent.
base: https://raw.githubusercontent.com/fullsend-ai/agents/7ab05564b3c9c0ab20197e0c8572b5905ffd75ca/harness/triage.yaml#sha256=3aa32e9f66ad6a9b60a75f50d3adc6ae39ebfb425c3928381e019436498bf2aa

allowed_remote_resources:
- https://raw.githubusercontent.com/fullsend-ai/agents/

env:
runner:
# Keep coding explicitly requested via /fs-code during this pilot.
TRIAGE_AUTO_CODE: "off"

trigger: >
event.source.system == "jira"
&& event.transition.kind == "comment_added"
&& has(event.transition.comment.command)
&& event.transition.comment.command == "/fs-triage"
&& event.entity.kind == "work_item"
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@
/.cursor/ @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-fullsend
/.fullsend/ @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-fullsend
/.github/workflows/fullsend.yaml @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-fullsend
/.github/workflows/fullsend-poll-jira.yml @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-fullsend
/.github/workflows/prioritize.yml @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-fullsend
143 changes: 143 additions & 0 deletions .github/workflows/fullsend-poll-jira.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Poll RHIDP for Fullsend commands intended for this repository.
#
# Fullsend resolves the command author's Jira role in RHIDP.
# Only /fs-triage and /fs-code are registered for
# Jira dispatch; other Fullsend commands remain out of scope.

name: fullsend Jira poll

on:
schedule:
- cron: "*/5 * * * *"
workflow_dispatch: {}

permissions: {}

jobs:
poll:
runs-on: ubuntu-24.04
permissions:
contents: read
concurrency:
group: fullsend-jira-poll
cancel-in-progress: false
outputs:
matrix: ${{ steps.build-matrix.outputs.matrix }}
has_dispatches: ${{ steps.build-matrix.outputs.has_dispatches }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- name: Install fullsend
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release download v0.43.0 --repo fullsend-ai/fullsend \
-p 'fullsend_0.43.0_linux_amd64.tar.gz' -O - | tar xz
sudo mv fullsend /usr/local/bin/
fullsend --version

- name: Poll Jira
env:
JIRA_TOKEN: ${{ secrets.JIRA_TOKEN }}
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
JIRA_BASE_URL: ${{ vars.JIRA_BASE_URL }}
TARGET_REPO: ${{ github.repository }}
run: |
set -euo pipefail
if [[ -z "${JIRA_BASE_URL}" ]]; then
echo "::error::JIRA_BASE_URL variable is empty (must be an Actions variable, not a secret)"
exit 1
fi
if [[ -z "${JIRA_TOKEN}" || -z "${JIRA_USER_EMAIL}" ]]; then
echo "::error::JIRA_TOKEN and JIRA_USER_EMAIL must be configured as Actions secrets"
exit 1
fi

poll_project() {
local project="$1"
local team_id="$2"
local output="dispatches-${project,,}.json"
# Keep each gate explicit. To enroll another team/project, add one
# poll_project call below with its Atlassian team ID.
local jql="project = ${project} AND cf[10001] = \"${team_id}\" AND labels = \"fullsend\" AND statusCategory != Done ORDER BY updated DESC"
echo "Polling ${project} for team ${team_id}; dispatching matches to ${TARGET_REPO}"
fullsend poll \
--input-driver jira-poll \
--mode slash \
--jira-url "${JIRA_BASE_URL}" \
--jira-project "${project}" \
--jql "${jql}" \
--target-repo "${TARGET_REPO}" \
--output "${output}" \
--fullsend-dir .fullsend
}

# Jira Team "RHDH AI" uses this Atlassian ID in cf[10001], not its display name.
RHDH_AI_TEAM_ID='ec74d716-af36-4b3c-950f-f79213d08f71-1087'
poll_project RHIDP "${RHDH_AI_TEAM_ID}"

jq -s 'add' dispatches-*.json > dispatches.json
echo "Dispatch count: $(jq 'length' dispatches.json)"
jq -c '.[] | {agent, event_type, status_number}' dispatches.json || true

- name: Upload dispatches.json
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
if: always()
with:
name: dispatches
path: dispatches.json
if-no-files-found: ignore

- name: Build dispatch matrix
id: build-matrix
run: |
set -euo pipefail
if [[ ! -f dispatches.json ]] || ! jq -e 'length > 0' dispatches.json > /dev/null 2>&1; then
echo "No dispatches."
echo 'matrix={"include":[]}' >> "${GITHUB_OUTPUT}"
echo "has_dispatches=false" >> "${GITHUB_OUTPUT}"
exit 0
fi

MATRIX=$(jq -c '{include: .}' dispatches.json)
DELIM="MATRIX_$(openssl rand -hex 8)"
{
echo "matrix<<${DELIM}"
printf '%s' "${MATRIX}"
echo
echo "${DELIM}"
} >> "${GITHUB_OUTPUT}"
echo "has_dispatches=true" >> "${GITHUB_OUTPUT}"

harness:
name: Harness
needs: poll
if: needs.poll.outputs.has_dispatches == 'true'
permissions:
actions: write
contents: write
id-token: write
issues: write
packages: read
pull-requests: write
uses: fullsend-ai/fullsend/.github/workflows/reusable-dispatch.yml@d5f36921ac754705619f38c637ef692873809fbc # v0.43.0
with:
matrix: ${{ needs.poll.outputs.matrix }}
install_mode: per-repo
mint_url: ${{ vars.FULLSEND_MINT_URL }}
gcp_region: ${{ vars.FULLSEND_GCP_REGION }}
jira_base_url: ${{ vars.JIRA_BASE_URL }}
runner_image: ubuntu-24.04
secrets:
FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }}
FULLSEND_GCP_PROJECT_ID: ${{ secrets.FULLSEND_GCP_PROJECT_ID }}
OTEL_EXPORTER_OTLP_TRACES_HEADERS: ${{ secrets.OTEL_EXPORTER_OTLP_TRACES_HEADERS }}
OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}
JIRA_TOKEN: ${{ secrets.JIRA_TOKEN }}
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
31 changes: 30 additions & 1 deletion docs/fullsend.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## What is fullsend?

[Fullsend](https://github.com/fullsend-ai/fullsend) is an agentic SDLC platform that provides AI-powered agents for triage, code review, code generation, and retrospectives. It runs as a GitHub Actions pipeline, triggered by GitHub events, and uses Vertex AI (Anthropic Claude) for inference.
[Fullsend](https://github.com/fullsend-ai/fullsend) is an agentic SDLC platform that provides AI-powered agents for triage, code review, code generation, and retrospectives. It runs as a GitHub Actions pipeline, triggered by GitHub events or the Jira poller, and uses Vertex AI (Anthropic Claude) for inference.

## Pilot scope

Expand Down Expand Up @@ -57,6 +57,35 @@ Available commands:
| `/fs-fix` | Fix issues flagged in a review |
| `/fs-fix-stop` | Disable fix agent for a PR (adds `fullsend-no-fix` label) |

### Jira pilot for RHDH AI

The [Jira poll workflow](../.github/workflows/fullsend-poll-jira.yml) checks
every five minutes for `/fs-triage` and `/fs-code` comments on RHIDP work
items. Fullsend checks the command author's Jira project role. The existing
GitHub Fullsend commands are unchanged.

Each Jira query requires all of these gates:

- Project: `RHIDP`.
- Jira `Team`: `RHDH AI`, selected by `cf[10001]` and its Atlassian team ID.
- Label: `fullsend` (agent opt-in).
- Status category is not Done.

Add the `fullsend` label to an eligible Jira work item before posting a
command. `/fs-triage` does not automatically start coding; use `/fs-code`
explicitly when implementation is ready. Grillme and spec commands are not
part of this Jira pilot.

To expand the cohort, add a project/team pair to the `poll_project` calls in
the workflow. Keep the `fullsend` opt-in label for each cohort.

Before enabling the scheduled workflow, configure the Actions variable
`JIRA_BASE_URL` and secrets `JIRA_TOKEN` and `JIRA_USER_EMAIL`. The workflow
fails visibly when any are missing. Its existing Fullsend GCP and mint
credentials are also required for the downstream agents. The RHDH AI team ID
comes from Parasol's poller for `https://stage-redhat.atlassian.net`; verify
the ID if `JIRA_BASE_URL` points to a different Jira instance.

## Coexistence with PR Agent

rhdh-plugins already has [PR Agent](https://github.com/Codium-ai/pr-agent) configured (`.pr_agent.toml`). Both agents run independently:
Expand Down
Loading