Drop strategy/ as a division — it's playbooks/runbooks, not agents (#595)

strategy/ holds 16 markdown files and ZERO have agent frontmatter — they're
playbooks (playbooks/phase-*.md), runbooks (runbooks/scenario-*.md), and briefs
(EXECUTIVE-BRIEF.md, QUICKSTART.md, nexus-strategy.md), not agent definitions.
There are 16 real agent divisions, 232 agents; strategy is not one of them.

#592 added `strategy` to lint-agents.sh AGENT_DIRS and the lint workflow paths
(to match divisions.json), which made CI lint those 16 frontmatter-less docs as
agents and fail every one with "missing frontmatter opening ---". So any PR
touching strategy/ broke CI. The original lint-agents.sh correctly excluded
strategy; #592 misread that deliberate exclusion as drift (same mistake as
integrations/ in #593).

Fix: remove strategy from convert.sh / lint-agents.sh AGENT_DIRS, the lint
workflow, and divisions.json; add it to NON_DIVISION_DIRS in check-divisions.sh.
divisions.json is now 16, matching the app's parse_agent count exactly.

Also add a content-derived backstop to check-divisions.sh: every division must
contain at least one .md with '---' frontmatter, or the build fails. This is
what stops a docs/playbook directory from being registered as an empty agent
division again — regardless of whether someone remembers the exclude list.

check-divisions.sh PASSES at 16; negative-tested that re-adding strategy fails
with "division 'strategy' has no agent files".

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Sitarzewski
2026-06-17 22:19:25 -05:00
committed by GitHub
parent 3f78a30bb2
commit 4d07efdb70
5 changed files with 27 additions and 8 deletions
+1 -2
View File
@@ -19,7 +19,6 @@ on:
- "support/**"
- "spatial-computing/**"
- "specialized/**"
- "strategy/**"
jobs:
lint:
@@ -36,7 +35,7 @@ jobs:
FILES=$(git diff --name-only --diff-filter=ACMR origin/${{ github.base_ref }}...HEAD -- \
'academic/**/*.md' 'design/**/*.md' 'engineering/**/*.md' 'finance/**/*.md' 'game-development/**/*.md' 'gis/**/*.md' 'marketing/**/*.md' 'paid-media/**/*.md' 'sales/**/*.md' 'security/**/*.md' 'product/**/*.md' \
'project-management/**/*.md' 'testing/**/*.md' 'support/**/*.md' \
'spatial-computing/**/*.md' 'specialized/**/*.md' 'strategy/**/*.md')
'spatial-computing/**/*.md' 'specialized/**/*.md')
{
echo "files<<ENDOFLIST"
echo "$FILES"
+1 -2
View File
@@ -1,5 +1,5 @@
{
"_note": "Source of truth for the agent division set. Each division (a top-level agent directory) maps to a display label, a Lucide icon name (PascalCase), and a brand color (hex). Consumed by the Agency Agents app and any other catalog tooling. scripts/check-divisions.sh (CI: check-divisions.yml) fails the build if this list disagrees with the directories on disk, the AGENT_DIRS arrays in scripts/convert.sh and scripts/lint-agents.sh, or the path filters in lint-agents.yml. To add a division: create its directory, add an entry here, then run scripts/check-divisions.sh and update wherever it points. NOT every top-level directory is a division: integrations/ holds per-tool conversion OUTPUTS written by scripts/convert.sh (not source agents) and is excluded via NON_DIVISION_DIRS in check-divisions.sh; examples/ and scripts/ are likewise excluded.",
"_note": "Source of truth for the agent division set. Each division (a top-level agent directory) maps to a display label, a Lucide icon name (PascalCase), and a brand color (hex). Consumed by the Agency Agents app and any other catalog tooling. scripts/check-divisions.sh (CI: check-divisions.yml) fails the build if this list disagrees with the directories on disk, the AGENT_DIRS arrays in scripts/convert.sh and scripts/lint-agents.sh, or the path filters in lint-agents.yml. To add a division: create its directory, add an entry here, then run scripts/check-divisions.sh and update wherever it points. NOT every top-level directory is a division: integrations/ holds per-tool conversion OUTPUTS written by scripts/convert.sh (not source agents); strategy/ holds playbooks and runbooks with no agent frontmatter; both — plus examples/ and scripts/ — are excluded via NON_DIVISION_DIRS in check-divisions.sh. A division must contain at least one frontmatter agent file.",
"divisions": {
"academic": { "label": "Academic", "icon": "GraduationCap", "color": "#8B5CF6" },
"design": { "label": "Design", "icon": "PenTool", "color": "#EC4899" },
@@ -15,7 +15,6 @@
"security": { "label": "Security", "icon": "ShieldCheck", "color": "#EF4444" },
"spatial-computing": { "label": "Spatial Computing", "icon": "Boxes", "color": "#06B6D4" },
"specialized": { "label": "Specialized", "icon": "Sparkles", "color": "#6366F1" },
"strategy": { "label": "Strategy", "icon": "Network", "color": "#F43F5E" },
"support": { "label": "Support", "icon": "LifeBuoy", "color": "#84CC16" },
"testing": { "label": "Testing", "icon": "FlaskConical", "color": "#F59E0B" }
}
+24 -2
View File
@@ -26,8 +26,10 @@ JSON="divisions.json"
# root that is a directory is treated as a division (so a new division dir is
# caught even if nobody remembered to register it).
# integrations/ is convert.sh's OUTPUT tree (per-tool conversions written back
# into the repo), not a source-agent category — it must never be scanned as one.
NON_DIVISION_DIRS=(examples scripts integrations)
# into the repo), not a source-agent category. strategy/ holds playbooks and
# runbooks (no agent frontmatter), not agents. Neither is a division — they must
# never be scanned as source-agent categories.
NON_DIVISION_DIRS=(examples scripts integrations strategy)
errors=0
fail() { echo "ERROR $*"; errors=$((errors + 1)); }
@@ -104,6 +106,26 @@ while IFS= read -r div; do
done
done < <(canonical)
# Every division must contain at least one agent file: a .md whose first line is
# '---' frontmatter. This is the content-derived backstop that keeps a docs or
# playbook directory (e.g. strategy/, all of whose files are frontmatter-less)
# from being registered as an empty agent division.
has_agent_file() {
local f first
while IFS= read -r f; do
first="$(head -1 "$f" | tr -d '\r')"
[[ "$first" == "---" ]] && return 0
done < <(find "$1" -name '*.md' -type f 2>/dev/null)
return 1
}
while IFS= read -r div; do
if [[ ! -d "$div" ]]; then
fail "division '$div' has no directory on disk"
elif ! has_agent_file "$div"; then
fail "division '$div' has no agent files (.md with '---' frontmatter) — not a real division"
fi
done < <(canonical)
# --- result ----------------------------------------------------------------
count="$(canonical | wc -l | tr -d ' ')"
+1 -1
View File
@@ -68,7 +68,7 @@ TODAY="$(date +%Y-%m-%d)"
AGENT_DIRS=(
academic design engineering finance game-development gis marketing paid-media product project-management
sales security spatial-computing specialized strategy support testing
sales security spatial-computing specialized support testing
)
# --- Usage ---
-1
View File
@@ -26,7 +26,6 @@ AGENT_DIRS=(
security
spatial-computing
specialized
strategy
support
testing
)