Skip to content
Merged
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
96 changes: 96 additions & 0 deletions .github/workflows/fullsend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# fullsend shim workflow
# Routes events to per-role agent dispatch workflows in .fullsend.
#
# Security: pull_request_target runs the BASE branch version of this workflow,
# preventing PRs from modifying it to exfiltrate the dispatch token.
# This shim never checks out PR code, so it is not vulnerable to "pwn request"
# attacks (see: Trivy CVE-2026-33634, hackerbot-claw campaign).
#
# The event payload is passed via an environment variable (not inline shell)
# to prevent script injection from attacker-controlled fields like issue
# titles, comment bodies, and PR descriptions.
name: fullsend

on:
issues:
types: [opened, edited, labeled]
issue_comment:
types: [created]
pull_request_target:
types: [opened, synchronize, ready_for_review]
pull_request_review:
types: [submitted]

jobs:
dispatch-triage:
runs-on: ubuntu-latest
if: >-
github.event_name == 'issues' ||
(github.event_name == 'issue_comment' && (
github.event.comment.body == '/triage' ||
startsWith(github.event.comment.body, '/triage ')
))
steps:
- name: Dispatch triage
env:
GH_TOKEN: ${{ secrets.FULLSEND_DISPATCH_TOKEN }}
EVENT_PAYLOAD: ${{ toJSON(github.event) }}
EVENT_TYPE: ${{ github.event_name }}
SOURCE_REPO: ${{ github.repository }}
DISPATCH_REPO: ${{ github.repository_owner }}/.fullsend
run: |
gh workflow run triage.yml \
--repo "$DISPATCH_REPO" \
--field event_type="$EVENT_TYPE" \
--field source_repo="$SOURCE_REPO" \
--field event_payload="$EVENT_PAYLOAD"

dispatch-code:
runs-on: ubuntu-latest
if: >-
(github.event_name == 'issues' && github.event.action == 'labeled'
&& github.event.label.name == 'ready-to-code') ||
(github.event_name == 'issue_comment' && (
github.event.comment.body == '/code' ||
startsWith(github.event.comment.body, '/code ')
))
steps:
- name: Dispatch code
env:
GH_TOKEN: ${{ secrets.FULLSEND_DISPATCH_TOKEN }}
EVENT_PAYLOAD: ${{ toJSON(github.event) }}
EVENT_TYPE: ${{ github.event_name }}
SOURCE_REPO: ${{ github.repository }}
DISPATCH_REPO: ${{ github.repository_owner }}/.fullsend
run: |
gh workflow run code.yml \
--repo "$DISPATCH_REPO" \
--field event_type="$EVENT_TYPE" \
--field source_repo="$SOURCE_REPO" \
--field event_payload="$EVENT_PAYLOAD"

dispatch-review:
runs-on: ubuntu-latest
if: >-
(github.event_name == 'issues' && github.event.action == 'labeled'
&& github.event.label.name == 'ready-for-review') ||
(github.event_name == 'issue_comment' && (
github.event.comment.body == '/review' ||
startsWith(github.event.comment.body, '/review ')
)) ||
github.event_name == 'pull_request_target' ||
github.event_name == 'pull_request_review'
steps:
- name: Dispatch review
env:
GH_TOKEN: ${{ secrets.FULLSEND_DISPATCH_TOKEN }}
EVENT_PAYLOAD: ${{ toJSON(github.event) }}
EVENT_TYPE: ${{ github.event_name }}
SOURCE_REPO: ${{ github.repository }}
DISPATCH_REPO: ${{ github.repository_owner }}/.fullsend
run: |
gh workflow run review.yml \
--repo "$DISPATCH_REPO" \
--field event_type="$EVENT_TYPE" \
--field source_repo="$SOURCE_REPO" \
--field event_payload="$EVENT_PAYLOAD"