Skip to content

Build GitHub Actions infrastructure for cross-repo Hats reviews and agentic task execution#3

Merged
AccidentalJedi merged 6 commits intomainfrom
copilot/setup-github-hooks-for-projects
Apr 10, 2026
Merged

Build GitHub Actions infrastructure for cross-repo Hats reviews and agentic task execution#3
AccidentalJedi merged 6 commits intomainfrom
copilot/setup-github-hooks-for-projects

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 10, 2026

Hat Stack was spec-only. This makes it operational — runnable in GitHub Actions as a service other repos can hook into, with a CLI for local agents (e.g., Copilot in VS Code) to dispatch both reviews and generative tasks against the Ollama Cloud model pool.

Review mode — 18-hat PR analysis pipeline

  • hats-review.yml — reusable workflow_call other repos reference directly; accepts diffs via inline content or artifact-based flow (diff_artifact input) for cross-workflow compatibility
  • hats-dispatch.ymlrepository_dispatch handler for API-triggered reviews with callback to source PR/issue
  • hats-self-review.yml — self-review on PRs to this repo
  • .github/actions/run-hats/action.yml — composite action for inline use in any workflow, uses $GITHUB_ACTION_PATH so forks run their own code
  • scripts/hats_runner.py — Conductor implementation: hat selection by diff triggers, tiered-parallel execution, cost budget gate (G1), security fast-path gate (G2), consolidation, Gold Hat/CoVE adjudication, risk score computation per CATALOG.md formula

Task mode — agentic work execution

  • hats-task.ymlrepository_dispatch + workflow_dispatch for generative tasks
  • scripts/hats_task_runner.py — 6 task types (generate_code, generate_docs, refactor, analyze, plan, test), each mapped to optimal hat with tier-aware model selection (Tier 1 tasks get Tier 1 models like glm-5.1, others use hat-assigned primaries). Primary hat generates, supporting hats review/enhance, Gold Hat does final QA.
  • scripts/hat — Bash CLI wrapping gh api dispatches with auto-detection of hat_stack repo from git remote. Local agent runs hat task generate_code "Build auth module" --repo org/app --pr 42, results post back as PR comment.
# Review a diff
git diff main | hat review - --repo myorg/app --pr 123

# Generate code via hat expertise
hat task generate_code "Build FastAPI auth with JWT" --repo myorg/app --pr 42

# Plan a migration
hat task plan "Migrate REST to GraphQL" --repo myorg/app --issue 10

Fork-friendly design

  • No hardcoded repo references — reusable workflow uses ${{ github.repository }} for checkout, composite action uses $GITHUB_ACTION_PATH, CLI auto-detects from git remote
  • Secrets never in code — all via ${{ secrets.* }} / os.environ
  • .env.example template, FORK_SETUP.md (fork → add one secret → done)
  • .gitignore hardened for credential files, runtime outputs
  • Preflight health-check in runners with actionable error messages

Configuration

  • scripts/hat_configs.yml — all 18 hats with model assignments per Implementation Guide §E2.2, personas, triggers, gate config, risk score weights. 8 models across 4 tiers (glm-5.1, kimi-k2.5, deepseek-v3.1, minimax-m2.7, nemotron-3-super, qwen3-coder, nemotron-3-nano, ministral-3).

Security hardening

  • Shell word-splitting prevention — all workflows use bash arrays ("${ARGS[@]}") instead of string concatenation for CLI arg construction
  • Python code injection prevention — prompts passed via environment variables instead of interpolation into inline Python literals
  • PR title injection preventionhats-self-review.yml sanitizes PR title via env var and tr before use in shell commands
  • GitHub Actions output injection — newline sanitization on all repository_dispatch payload values written to GITHUB_OUTPUT
  • Null-safe artifact handlingfind -print0 pattern for safe filename handling in artifact downloads
  • Shell injection in hat CLI — variables passed via os.environ instead of string interpolation

Copilot AI and others added 4 commits April 9, 2026 23:40
…nd README update

Agent-Logs-Url: https://github.com/Grumpified-OGGVCT/hat_stack/sessions/0d30553c-4fdf-40c8-ac6c-392b98ed83ef

Co-authored-by: AccidentalJedi <92951150+AccidentalJedi@users.noreply.github.com>
…and documentation

Agent-Logs-Url: https://github.com/Grumpified-OGGVCT/hat_stack/sessions/0d30553c-4fdf-40c8-ac6c-392b98ed83ef

Co-authored-by: AccidentalJedi <92951150+AccidentalJedi@users.noreply.github.com>
…tion in CLI, fix empty list edge case

Agent-Logs-Url: https://github.com/Grumpified-OGGVCT/hat_stack/sessions/0d30553c-4fdf-40c8-ac6c-392b98ed83ef

Co-authored-by: AccidentalJedi <92951150+AccidentalJedi@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 10, 2026

🎩 Hats Team Review Report

✅ Verdict: ALLOW (Risk Score: 0/100)

Severity Summary

Severity Count
🔴 CRITICAL 0
🟠 HIGH 0
🟡 MEDIUM 0
🟢 LOW 0

Hat Execution Summary

Hat Model Latency Findings Status
🔴 Red Hat — Failure & Resilience nemotron-3-super 0.1s 0 ❌ Error
⚪ White Hat — Efficiency & Resources ministral-3 0.1s 0 ❌ Error
⚫ Black Hat — Security & Exploits deepseek-v3.1 0.1s 0 ❌ Error
🟡 Yellow Hat — Synergies & Integration nemotron-3-super 0.1s 0 ❌ Error
🔵 Blue Hat — Process & Specification ministral-3 0.1s 0 ❌ Error
🟢 Green Hat — Evolution & Extensibility minimax-m2.7 0.1s 0 ❌ Error
🟠 Orange Hat — DevOps & Automation nemotron-3-super 0.1s 0 ❌ Error
🟣 Indigo Hat — Cross-Feature Architecture nemotron-3-super 0.1s 0 ❌ Error
💎 Azure Hat — MCP & Protocol Integration qwen3-coder 0.1s 0 ❌ Error
🩵 Cyan Hat — Innovation & Feasibility minimax-m2.7 0.1s 0 ❌ Error
🟪 Purple Hat — AI Safety & Alignment deepseek-v3.1 0.1s 0 ❌ Error
🟤 Brown Hat — Data Governance & Privacy deepseek-v3.1 0.1s 0 ❌ Error
🔗 Steel Hat — Supply Chain & Dependencies nemotron-3-nano 0.0s 0 ❌ Error
🧪 Chartreuse Hat — Testing & Evaluation qwen3-coder 0.0s 0 ❌ Error
⚙️ Gray Hat — Observability & Reliability nemotron-3-super 0.1s 0 ❌ Error
♿ Teal Hat — Accessibility & Inclusion ministral-3 0.1s 0 ❌ Error
✨ Gold Hat — CoVE Final QA glm-5.1 0.0s 0 ❌ Error

Pipeline Stats

  • Hats Selected: 17
  • Hats Executed: 17
  • Hats Failed: 17
  • Total Tokens: 0

Copy link
Copy Markdown

Copilot AI left a comment

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 makes Hat Stack operational by adding GitHub Actions workflows, runner scripts, configuration, and documentation so other repositories (and local agents via hat CLI) can dispatch reviews and agentic tasks executed against the configured Ollama model pool.

Changes:

  • Adds Python orchestrators for review (scripts/hats_runner.py) and task execution (scripts/hats_task_runner.py) plus the hat/model config (scripts/hat_configs.yml).
  • Adds GitHub Actions workflows for reusable reviews, dispatch-triggered reviews, task execution, and self-review.
  • Adds a hat CLI wrapper and fork/setup documentation/templates for secret management.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
scripts/requirements.txt Adds Python dependencies for runners (PyYAML, requests).
scripts/hats_task_runner.py Implements task-mode orchestration (hat selection, parallel supporting hats, output writing).
scripts/hats_runner.py Implements review-mode orchestration (hat selection, gates, execution, consolidation, reporting).
scripts/hat_configs.yml Defines hats, models, gates, execution settings, and risk scoring weights.
scripts/hat Adds a gh api-based CLI for dispatching reviews/tasks to Hat Stack.
README.md Documents GitHub Actions integration, task mode usage, and repo layout.
FORK_SETUP.md Provides fork-friendly setup/integration guide and examples.
.gitignore Adds secret/runtime-output ignore patterns.
.github/workflows/hats-task.yml Adds repository/workflow dispatch handler for task execution + callback posting.
.github/workflows/hats-self-review.yml Adds self-review workflow to run Hats on PRs to this repo.
.github/workflows/hats-review.yml Adds reusable workflow for other repos to call for reviews.
.github/workflows/hats-dispatch.yml Adds repository_dispatch handler for review requests + callback posting.
.github/actions/run-hats/action.yml Adds composite action to run Hats review in any workflow.
.env.example Adds environment template for local usage and optional settings.

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

Comment on lines +174 to +189
ARGS="--task ${{ steps.params.outputs.task }}"
ARGS="$ARGS --prompt '${{ steps.params.outputs.prompt }}'"
ARGS="$ARGS --config scripts/hat_configs.yml"
ARGS="$ARGS --output /tmp/hats-task-output"
ARGS="$ARGS --json-file /tmp/hats-task-result.json"

if [ -n "${{ steps.params.outputs.hats }}" ]; then
ARGS="$ARGS --hats ${{ steps.params.outputs.hats }}"
fi

if [ -d "/tmp/hats-context" ] && [ "$(ls -A /tmp/hats-context 2>/dev/null)" ]; then
ARGS="$ARGS --context-dir /tmp/hats-context"
fi

set +e
python scripts/hats_task_runner.py $ARGS
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

Building CLI args in a single string and then invoking python ... $ARGS is vulnerable to shell word-splitting and quote-breaking. steps.params.outputs.prompt comes from user-controlled dispatch payload and is only newline-sanitized, so a prompt containing a single quote or shell metacharacters can break the command or inject extra flags. Construct the command with a bash array (or pass values via env / a temp file) and quote each argument when invoking Python.

Suggested change
ARGS="--task ${{ steps.params.outputs.task }}"
ARGS="$ARGS --prompt '${{ steps.params.outputs.prompt }}'"
ARGS="$ARGS --config scripts/hat_configs.yml"
ARGS="$ARGS --output /tmp/hats-task-output"
ARGS="$ARGS --json-file /tmp/hats-task-result.json"
if [ -n "${{ steps.params.outputs.hats }}" ]; then
ARGS="$ARGS --hats ${{ steps.params.outputs.hats }}"
fi
if [ -d "/tmp/hats-context" ] && [ "$(ls -A /tmp/hats-context 2>/dev/null)" ]; then
ARGS="$ARGS --context-dir /tmp/hats-context"
fi
set +e
python scripts/hats_task_runner.py $ARGS
ARGS=(
--task "${{ steps.params.outputs.task }}"
--prompt "${{ steps.params.outputs.prompt }}"
--config scripts/hat_configs.yml
--output /tmp/hats-task-output
--json-file /tmp/hats-task-result.json
)
if [ -n "${{ steps.params.outputs.hats }}" ]; then
ARGS+=(--hats "${{ steps.params.outputs.hats }}")
fi
if [ -d "/tmp/hats-context" ] && [ "$(ls -A /tmp/hats-context 2>/dev/null)" ]; then
ARGS+=(--context-dir /tmp/hats-context)
fi
set +e
python scripts/hats_task_runner.py "${ARGS[@]}"

Copilot uses AI. Check for mistakes.
Comment on lines +110 to +125
ARGS="--diff ${{ steps.diff.outputs.diff_file }}"
ARGS="$ARGS --config scripts/hat_configs.yml"
ARGS="$ARGS --output both"
ARGS="$ARGS --markdown-file /tmp/hats-report.md"
ARGS="$ARGS --json-file /tmp/hats-report.json"

if [ -n "${{ steps.payload.outputs.hats }}" ]; then
ARGS="$ARGS --hats ${{ steps.payload.outputs.hats }}"
fi

if [ -n "${{ steps.payload.outputs.context }}" ]; then
ARGS="$ARGS --context '${{ steps.payload.outputs.context }}'"
fi

set +e
python scripts/hats_runner.py $ARGS
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

context is interpolated into a single-quoted string inside an ARGS accumulator and then executed via python ... $ARGS. Since context originates from repository_dispatch payload and is only newline-sanitized, a single quote (or other shell metacharacters) can break quoting and potentially inject additional CLI flags. Prefer invoking Python with properly quoted args (bash array) instead of building a string.

Suggested change
ARGS="--diff ${{ steps.diff.outputs.diff_file }}"
ARGS="$ARGS --config scripts/hat_configs.yml"
ARGS="$ARGS --output both"
ARGS="$ARGS --markdown-file /tmp/hats-report.md"
ARGS="$ARGS --json-file /tmp/hats-report.json"
if [ -n "${{ steps.payload.outputs.hats }}" ]; then
ARGS="$ARGS --hats ${{ steps.payload.outputs.hats }}"
fi
if [ -n "${{ steps.payload.outputs.context }}" ]; then
ARGS="$ARGS --context '${{ steps.payload.outputs.context }}'"
fi
set +e
python scripts/hats_runner.py $ARGS
ARGS=(
--diff "${{ steps.diff.outputs.diff_file }}"
--config scripts/hat_configs.yml
--output both
--markdown-file /tmp/hats-report.md
--json-file /tmp/hats-report.json
)
if [ -n "${{ steps.payload.outputs.hats }}" ]; then
ARGS+=( --hats "${{ steps.payload.outputs.hats }}" )
fi
if [ -n "${{ steps.payload.outputs.context }}" ]; then
ARGS+=( --context "${{ steps.payload.outputs.context }}" )
fi
set +e
python scripts/hats_runner.py "${ARGS[@]}"

Copilot uses AI. Check for mistakes.
Comment on lines +139 to +155
ARGS="--diff ${{ steps.diff.outputs.diff_file }}"
ARGS="$ARGS --config ${{ steps.config.outputs.config_path }}"
ARGS="$ARGS --output ${{ inputs.output_format }}"
ARGS="$ARGS --markdown-file /tmp/hats-report.md"
ARGS="$ARGS --json-file /tmp/hats-report.json"

if [ -n "${{ inputs.hats }}" ]; then
ARGS="$ARGS --hats ${{ inputs.hats }}"
fi

if [ -n "${{ inputs.context }}" ]; then
ARGS="$ARGS --context '${{ inputs.context }}'"
fi

# Run the pipeline — capture exit code but don't fail yet
set +e
python hat_stack/scripts/hats_runner.py $ARGS
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

inputs.context is embedded in a single-quoted segment of an ARGS string and then executed as python ... $ARGS. If the context contains a single quote, it will break the shell quoting and can change the invoked arguments. Use a bash array and pass --context as a separate, properly quoted argument (or write context to a file and have the runner read it).

Suggested change
ARGS="--diff ${{ steps.diff.outputs.diff_file }}"
ARGS="$ARGS --config ${{ steps.config.outputs.config_path }}"
ARGS="$ARGS --output ${{ inputs.output_format }}"
ARGS="$ARGS --markdown-file /tmp/hats-report.md"
ARGS="$ARGS --json-file /tmp/hats-report.json"
if [ -n "${{ inputs.hats }}" ]; then
ARGS="$ARGS --hats ${{ inputs.hats }}"
fi
if [ -n "${{ inputs.context }}" ]; then
ARGS="$ARGS --context '${{ inputs.context }}'"
fi
# Run the pipeline — capture exit code but don't fail yet
set +e
python hat_stack/scripts/hats_runner.py $ARGS
ARGS=(
--diff "${{ steps.diff.outputs.diff_file }}"
--config "${{ steps.config.outputs.config_path }}"
--output "${{ inputs.output_format }}"
--markdown-file /tmp/hats-report.md
--json-file /tmp/hats-report.json
)
if [ -n "${{ inputs.hats }}" ]; then
ARGS+=(--hats "${{ inputs.hats }}")
fi
if [ -n "${{ inputs.context }}" ]; then
ARGS+=(--context "${{ inputs.context }}")
fi
# Run the pipeline — capture exit code but don't fail yet
set +e
python hat_stack/scripts/hats_runner.py "${ARGS[@]}"

Copilot uses AI. Check for mistakes.
Comment on lines +111 to +126
ARGS="--diff ${{ steps.prep.outputs.diff_file }}"
ARGS="$ARGS --config $CONFIG"
ARGS="$ARGS --output ${{ inputs.output_format }}"
ARGS="$ARGS --markdown-file /tmp/hats-report.md"
ARGS="$ARGS --json-file /tmp/hats-report.json"

if [ -n "${{ inputs.hats }}" ]; then
ARGS="$ARGS --hats ${{ inputs.hats }}"
fi

if [ -n "${{ inputs.context }}" ]; then
ARGS="$ARGS --context '${{ inputs.context }}'"
fi

set +e
python _hat_stack/scripts/hats_runner.py $ARGS
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

The composite action builds a command line by concatenating to ARGS and then running python ... $ARGS. inputs.context can contain single quotes and other characters that break shell quoting, allowing argument injection. Use a bash array (e.g., args=(--diff ... --context "$INPUT")) and call Python with "${args[@]}".

Suggested change
ARGS="--diff ${{ steps.prep.outputs.diff_file }}"
ARGS="$ARGS --config $CONFIG"
ARGS="$ARGS --output ${{ inputs.output_format }}"
ARGS="$ARGS --markdown-file /tmp/hats-report.md"
ARGS="$ARGS --json-file /tmp/hats-report.json"
if [ -n "${{ inputs.hats }}" ]; then
ARGS="$ARGS --hats ${{ inputs.hats }}"
fi
if [ -n "${{ inputs.context }}" ]; then
ARGS="$ARGS --context '${{ inputs.context }}'"
fi
set +e
python _hat_stack/scripts/hats_runner.py $ARGS
args=(
--diff "${{ steps.prep.outputs.diff_file }}"
--config "$CONFIG"
--output "${{ inputs.output_format }}"
--markdown-file /tmp/hats-report.md
--json-file /tmp/hats-report.json
)
if [ -n "${{ inputs.hats }}" ]; then
args+=(--hats "${{ inputs.hats }}")
fi
if [ -n "${{ inputs.context }}" ]; then
args+=(--context "${{ inputs.context }}")
fi
set +e
python _hat_stack/scripts/hats_runner.py "${args[@]}"

Copilot uses AI. Check for mistakes.
Comment on lines +189 to +200
def select_model_for_task(config: dict, hat_id: str, task_type: str) -> str:
"""Select the best model for a task, using task tier as a guide."""
hats_cfg = config["hats"]
hat_def = hats_cfg.get(hat_id, {})
profile = TASK_PROFILES.get(task_type, {})

# For Tier 1 tasks, always use the primary (best) model
if profile.get("model_tier", 2) == 1:
return hat_def.get("primary_model", "glm-5.1")

return hat_def.get("primary_model", "glm-5.1")

Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

select_model_for_task() does not actually vary the selected model by model_tier—both Tier 1 and non–Tier 1 paths return primary_model. This contradicts the intent implied by the docstring and the task profiles (and the PR description’s claim of tier-based model selection). Either implement tier-aware selection (e.g., map tier→model in config) or remove the unused tier logic to avoid misleading behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +122 to +130
- name: Determine config
id: config
shell: bash
run: |
if [ -n "${{ inputs.config_override }}" ] && [ -f "${{ inputs.config_override }}" ]; then
echo "config_path=${{ inputs.config_override }}" >> "$GITHUB_OUTPUT"
else
echo "config_path=hat_stack/scripts/hat_configs.yml" >> "$GITHUB_OUTPUT"
fi
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

inputs.config_override is described as a path in the calling repo, but this workflow only checks out hat_stack and never checks out the caller repo (nor downloads artifacts). As a result the -f check will be false and the override can’t be used. If override support is needed, add a mechanism to supply the config (inline string, artifact download, or a second checkout of the caller repo).

Copilot uses AI. Check for mistakes.
Comment on lines +104 to +110
hats-review:
needs: get-diff
# Point this to YOUR fork:
uses: YOUR_USERNAME/hat_stack/.github/workflows/hats-review.yml@main
secrets:
ollama_api_key: ${{ secrets.OLLAMA_API_KEY }}
```
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

The reusable-workflow example never passes the generated diff into the called workflow (there’s no with: diff or with: diff_file). Also, even if diff_file were passed, a workflow_call job won’t see the caller job’s filesystem path; you’d need to pass the diff content directly or download the pr-diff artifact inside the called workflow. As written, this Quick Start snippet won’t actually run a review.

Copilot uses AI. Check for mistakes.
Comment on lines +141 to +149
**Option A — Reusable Workflow** (recommended):
```yaml
# In your other repo: .github/workflows/hats.yml
jobs:
hats-review:
uses: YOUR_USERNAME/hat_stack/.github/workflows/hats-review.yml@main
secrets:
ollama_api_key: ${{ secrets.OLLAMA_API_KEY }}
```
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

The reusable-workflow usage snippet is missing the required with: inputs (diff or diff_file). As shown, the called workflow will exit early with “No diff provided”. Update the example to demonstrate passing a diff (and, if using diff_file, also explain how the called workflow can access it—typically via artifacts rather than a raw filesystem path).

Copilot uses AI. Check for mistakes.
Comment on lines +97 to +104
# Prompt may contain special chars — sanitize newlines
python3 -c "
import os, re
val = '''${{ inputs.prompt }}'''
sanitized = re.sub(r'[\r\n]', ' ', val).strip()
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
f.write(f'prompt={sanitized}\n')
"
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

In the workflow_dispatch path, inputs.prompt is interpolated directly into a python3 -c snippet inside a triple-quoted string (val = '''${{ inputs.prompt }}'''). A prompt containing ''' (or other crafted content) can break out of the string and inject arbitrary Python code. Avoid embedding untrusted inputs into inline code; pass the prompt via stdin/env and have Python read it, or write it to $GITHUB_OUTPUT using a heredoc delimiter (prompt<<EOF).

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +56
shell: bash
run: |
set +e
python scripts/hats_runner.py \
--diff /tmp/pr-diff.patch \
--config scripts/hat_configs.yml \
--output both \
--markdown-file /tmp/hats-report.md \
--json-file /tmp/hats-report.json \
--context "Self-review of hat_stack PR #${{ github.event.pull_request.number }}: ${{ github.event.pull_request.title }}"
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

github.event.pull_request.title is interpolated into a double-quoted --context argument without sanitization. A PR title containing ", backticks, $(), newlines, etc. can break shell quoting and potentially inject additional shell tokens/commands. Sanitize the title (e.g., strip newlines/quotes) and pass it as a separate, properly quoted argument (bash array), or write the context to a file and have the runner read it.

Suggested change
shell: bash
run: |
set +e
python scripts/hats_runner.py \
--diff /tmp/pr-diff.patch \
--config scripts/hat_configs.yml \
--output both \
--markdown-file /tmp/hats-report.md \
--json-file /tmp/hats-report.json \
--context "Self-review of hat_stack PR #${{ github.event.pull_request.number }}: ${{ github.event.pull_request.title }}"
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
shell: bash
run: |
set +e
SANITIZED_PR_TITLE=$(printf '%s' "$PR_TITLE" | tr '\r\n' ' ' | tr '"' "'")
CONTEXT="Self-review of hat_stack PR #$PR_NUMBER: $SANITIZED_PR_TITLE"
cmd=(
python scripts/hats_runner.py
--diff /tmp/pr-diff.patch
--config scripts/hat_configs.yml
--output both
--markdown-file /tmp/hats-report.md
--json-file /tmp/hats-report.json
--context "$CONTEXT"
)
"${cmd[@]}"

Copilot uses AI. Check for mistakes.
@AccidentalJedi
Copy link
Copy Markdown
Contributor

@copilot apply changes based on the comments in this thread if you can invoke and use the hats in your work, do so.

Copilot AI and others added 2 commits April 10, 2026 00:14
…ll word-splitting, fork-friendliness, tier-aware models, docs

- Use bash arrays for all CLI arg construction in workflows
- Pass prompt via env var instead of triple-quoted Python literal
- Sanitize PR title in self-review via env var and tr
- Make hats-review.yml fork-friendly with ${{ github.repository }}
- Make composite action use $GITHUB_ACTION_PATH instead of hardcoded repo
- Implement auto-detect in hat CLI from git remote
- Implement tier-aware model selection in task runner
- Fix consolidate_reports docstring
- Switch hats-review.yml to artifact-based diff flow
- Remove broken config_override input
- Remove undocumented HATS_TIER*_MODEL env vars from docs
- Fix README and FORK_SETUP examples to pass diff correctly

Agent-Logs-Url: https://github.com/Grumpified-OGGVCT/hat_stack/sessions/0d46a63d-1e08-41a4-8cd7-c5fb2d479564

Co-authored-by: AccidentalJedi <92951150+AccidentalJedi@users.noreply.github.com>
…t HAT_STACK_ROOT var, null-safe find

Agent-Logs-Url: https://github.com/Grumpified-OGGVCT/hat_stack/sessions/0d46a63d-1e08-41a4-8cd7-c5fb2d479564

Co-authored-by: AccidentalJedi <92951150+AccidentalJedi@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 10, 2026

@copilot apply changes based on the comments in this thread if you can invoke and use the hats in your work, do so...

All 16 review comments addressed in commits 25a3a54 and bf48aab:

Security (7 fixes): All workflow CLI args now use bash arrays instead of string concatenation. Prompt passed via INPUT_PROMPT env var instead of triple-quoted Python. PR title sanitized via env var + tr. Null-safe find with -print0 for artifact filenames.

Fork-friendliness (4 fixes): hats-review.yml uses ${{ github.repository }} instead of hardcoded upstream. Composite action uses $GITHUB_ACTION_PATH instead of separate checkout. hat CLI auto-detects repo from git remote. Removed hardcoded repo references.

Correctness (3 fixes): select_model_for_task() now actually varies by tier — Tier 1 tasks get Tier 1 models, others use the hat's assigned primary. consolidate_reports() docstring corrected. Reusable workflow switched to artifact-based diff flow (diff_artifact input) since workflow_call jobs don't share filesystems.

Docs (2 fixes): Removed undocumented HATS_TIER*_MODEL env vars from FORK_SETUP.md. Fixed README and FORK_SETUP examples to correctly pass diff via artifact.

@AccidentalJedi
Copy link
Copy Markdown
Contributor

@copilot apply changes based on the comments in this thread use the hat stack if it's helpful

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 10, 2026

@copilot apply changes based on the comments in this thread use the hat stack if it's helpful

All 16 review comments from that thread were already applied in commits 25a3a54 and bf48aab. I've verified every item is in place — bash arrays for arg construction, env-var-based prompt/title passing, ${{ github.repository }} and $GITHUB_ACTION_PATH for fork-friendliness, tier-aware model selection, artifact-based diff flow, and corrected docs/examples.

@AccidentalJedi AccidentalJedi merged commit d5be91f into main Apr 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants