From e1e51d7df43d504953b68205427e8fb9b42e0e01 Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Fri, 8 May 2026 22:51:10 -0400 Subject: [PATCH 1/3] chore: add lint-workflow-size to cap workflow file growth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Workflow files are GitHub-specific glue. Logic that accumulates in them binds us to GitHub Actions and can't be unit tested. This linter caps workflow YAML files at 200 lines by default, encouraging extraction to scripts/ (the established pattern). Files that are already over the cap get per-file overrides via a comment (e.g. # lint-workflow-size: max-lines=310). The cap can be raised intentionally — the linter just makes growth visible and reviewable. Covers both .fullsend agent workflows and the shim template. References ADR-0005 (forge abstraction layer). Co-Authored-By: Claude Opus 4.6 --- .pre-commit-config.yaml | 7 ++ hack/lint-workflow-size | 76 +++++++++++++++++++ .../fullsend-repo/.github/workflows/fix.yml | 1 + .../workflows/prioritize-scheduler.yml | 1 + .../templates/shim-workflow.yaml | 1 + 5 files changed, 86 insertions(+) create mode 100755 hack/lint-workflow-size diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 40e5c18dc..e6eccb8dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -92,3 +92,10 @@ repos: language: system pass_filenames: false always_run: true + + - id: lint-workflow-size + name: lint workflow file size + entry: ./hack/lint-workflow-size + language: script + files: ^internal/scaffold/fullsend-repo/(\.github/workflows/|templates/) + pass_filenames: false diff --git a/hack/lint-workflow-size b/hack/lint-workflow-size new file mode 100755 index 000000000..564390f50 --- /dev/null +++ b/hack/lint-workflow-size @@ -0,0 +1,76 @@ +#!/bin/bash + +# lint-workflow-size - Guard against logic accumulating in workflow YAML files +# +# Workflow files are GitHub-specific glue. Business logic, shell scripts, and +# agent plumbing should live in scripts/ where they can be tested, reused, and +# ported to other forges. +# +# See: +# ADR-0005 Forge abstraction layer +# ADR-0008 workflow_dispatch for cross-repo agent dispatch +# +# Default cap: 200 lines per workflow file. To raise the cap for a specific +# file, add a comment anywhere in the YAML: +# +# # lint-workflow-size: max-lines=350 +# +# This forces an intentional, reviewable decision rather than silent growth. + +set -euo pipefail + +DEFAULT_MAX=200 +errors=0 + +check_files() { + local dir="$1" + + if [[ ! -d "${dir}" ]]; then + return + fi + + for file in "${dir}"/*.yml "${dir}"/*.yaml; do + [[ -e "${file}" ]] || continue + + lines=$(wc -l < "${file}") + filename=$(basename "${file}") + relpath="${file}" + + # Check for per-file override + max="${DEFAULT_MAX}" + override=$(grep -oP '# lint-workflow-size: max-lines=\K[0-9]+' "${file}" 2>/dev/null | tail -1 || true) + if [[ -n "${override}" ]]; then + max="${override}" + fi + + if [[ "${lines}" -gt "${max}" ]]; then + echo "ERROR: ${relpath} is ${lines} lines (max ${max})" >&2 + echo "" >&2 + echo " Workflow files are GitHub-specific glue — keep logic in scripts/" >&2 + echo " where it can be tested and ported to other forges." >&2 + echo " See ADR-0005 (forge abstraction layer)." >&2 + echo "" >&2 + echo " To fix: extract inline shell into scripts/ and call with" >&2 + echo " run: bash scripts/your-script.sh" >&2 + echo "" >&2 + echo " To raise the cap (if the size is justified), add this comment" >&2 + echo " to the file:" >&2 + echo " # lint-workflow-size: max-lines=" >&2 + echo "" >&2 + errors=$((errors + 1)) + fi + done +} + +# Agent workflow files in the .fullsend repo scaffold +check_files "internal/scaffold/fullsend-repo/.github/workflows" + +# Shim workflow template (deployed to enrolled repos) +check_files "internal/scaffold/fullsend-repo/templates" + +if [[ "${errors}" -gt 0 ]]; then + echo "FAILED: ${errors} workflow file(s) exceed size limit" >&2 + exit 1 +else + echo "OK: All workflow files within size limits" +fi diff --git a/internal/scaffold/fullsend-repo/.github/workflows/fix.yml b/internal/scaffold/fullsend-repo/.github/workflows/fix.yml index 33a02082c..298b02086 100644 --- a/internal/scaffold/fullsend-repo/.github/workflows/fix.yml +++ b/internal/scaffold/fullsend-repo/.github/workflows/fix.yml @@ -1,4 +1,5 @@ # fullsend-stage: fix +# lint-workflow-size: max-lines=310 name: Fix on: diff --git a/internal/scaffold/fullsend-repo/.github/workflows/prioritize-scheduler.yml b/internal/scaffold/fullsend-repo/.github/workflows/prioritize-scheduler.yml index 8592db785..27c65247c 100644 --- a/internal/scaffold/fullsend-repo/.github/workflows/prioritize-scheduler.yml +++ b/internal/scaffold/fullsend-repo/.github/workflows/prioritize-scheduler.yml @@ -1,3 +1,4 @@ +# lint-workflow-size: max-lines=220 name: Prioritize Scheduler on: diff --git a/internal/scaffold/fullsend-repo/templates/shim-workflow.yaml b/internal/scaffold/fullsend-repo/templates/shim-workflow.yaml index c5ff9ee39..2d401d4ae 100644 --- a/internal/scaffold/fullsend-repo/templates/shim-workflow.yaml +++ b/internal/scaffold/fullsend-repo/templates/shim-workflow.yaml @@ -1,3 +1,4 @@ +# lint-workflow-size: max-lines=475 # fullsend shim workflow # Routes events to agent workflows in .fullsend via the dispatch.yml workflow. # From fd8a3db9dfd1ef04e38bbe0d6fec1dbd3b4b97cb Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Mon, 11 May 2026 10:17:23 -0400 Subject: [PATCH 2/3] fix: bump shim-workflow size cap to 535 (was 475, file grew to 529) The shim-workflow.yaml grew past the 475-line cap after concurrent merges landed on main. Bump the override to 535 to accommodate the current 529 lines with a small buffer. Co-Authored-By: Claude Opus 4.6 --- internal/scaffold/fullsend-repo/templates/shim-workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/scaffold/fullsend-repo/templates/shim-workflow.yaml b/internal/scaffold/fullsend-repo/templates/shim-workflow.yaml index 2d401d4ae..e3767087e 100644 --- a/internal/scaffold/fullsend-repo/templates/shim-workflow.yaml +++ b/internal/scaffold/fullsend-repo/templates/shim-workflow.yaml @@ -1,4 +1,4 @@ -# lint-workflow-size: max-lines=475 +# lint-workflow-size: max-lines=535 # fullsend shim workflow # Routes events to agent workflows in .fullsend via the dispatch.yml workflow. # From 5dec679e97b3cc8f2b4f33d2a7bbc2172b70e7ec Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Mon, 11 May 2026 10:22:38 -0400 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20address=20review=20findings=20?= =?UTF-8?q?=E2=80=94=20bump=20stale=20cap,=20fix=20grep=20portability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bump shim-workflow.yaml max-lines from 475 to 535 (file grew to 529 after PR #785 merged) - Replace grep -oP (PCRE, Linux-only) with POSIX-compatible grep chain so the override detection works on macOS BSD grep too Addresses both findings from fullsend-ai-review. Co-Authored-By: Claude Opus 4.6 --- hack/lint-workflow-size | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/lint-workflow-size b/hack/lint-workflow-size index 564390f50..3c7a6a907 100755 --- a/hack/lint-workflow-size +++ b/hack/lint-workflow-size @@ -38,7 +38,7 @@ check_files() { # Check for per-file override max="${DEFAULT_MAX}" - override=$(grep -oP '# lint-workflow-size: max-lines=\K[0-9]+' "${file}" 2>/dev/null | tail -1 || true) + override=$(grep -o 'max-lines=[0-9]*' "${file}" 2>/dev/null | grep -o '[0-9]*' | tail -1 || true) if [[ -n "${override}" ]]; then max="${override}" fi