| name | check-makefile |
| description | Audits a top-level Makefile against 29 deterministic checks (strict-shell pin, `.SHELLFLAGS`, `MAKEFLAGS` warnings, `.PHONY` coverage, tab-indent, header comment, help-target patterns, variable-assignment discipline, top-level shell, destructive-op guards including `rm -rf`/`sudo`/global-install/curl-pipe, recipe hygiene, secrets, file/line size, optional `checkmake` wrap) plus seven judgment dimensions and a Tier-3 cross-Makefile collision check. Use when the user wants to "audit a makefile", "lint a makefile", or "review this makefile". Not for POSIX-`make`, compilation trees, or recursive multi-module builds — different rubric.
|
| allowed-tools | Read, Write, Edit, Bash, Grep, Glob |
| argument-hint | [path] |
| user-invocable | true |
| references | ["../../_shared/references/makefile-best-practices.md","references/check-collision.md","references/check-destructive-op-safety.md","references/check-documentation-intent.md","references/check-incremental-correctness.md","references/check-naming-and-structure.md","references/check-recipe-hygiene.md","references/check-target-contract-integrity.md","references/check-variable-and-override-discipline.md"] |
| license | MIT |
Check Makefile
Audit a top-level Makefile for structural soundness, safety, help/.PHONY coverage, recipe hygiene, and adherence to the workflow-orchestration rubric. The rubric — what makes a Makefile load-bearing, the anatomy template, the patterns that work — lives in makefile-best-practices.md.
This skill follows the check-skill pattern. Tier-1 detection is in 11 scripts emitting JSON envelopes via _common.py (29 rule_ids total). Tier-2 has 7 judgment dimensions read inline by the primary agent. Tier-3 is collision (cross-Makefile drift in multi-Makefile scope).
When to use
Also fires when the user phrases the request as:
- "check my makefile"
- "is my makefile any good"
- "what's wrong with my makefile"
Workflow
1. Scope
Read $ARGUMENTS:
- Single path to a
Makefile (or *.mk file) — audit that file.
- Directory path — walk the top level for
Makefile, GNUmakefile, *.mk. Do not recurse — recursive multi-module builds are out of scope.
- Empty — refuse and explain.
Confirm scope aloud.
2. Tier-1 Deterministic Checks
Invoke 11 detection scripts:
SCRIPTS="${SKILL_DIR}/scripts"
TARGETS="$ARGUMENTS"
python3 "$SCRIPTS/check_secrets.py" $TARGETS
python3 "$SCRIPTS/check_structure.py" $TARGETS
python3 "$SCRIPTS/check_phony.py" $TARGETS
python3 "$SCRIPTS/check_help.py" $TARGETS
python3 "$SCRIPTS/check_indent.py" $TARGETS
python3 "$SCRIPTS/check_naming.py" $TARGETS
python3 "$SCRIPTS/check_variables.py" $TARGETS
python3 "$SCRIPTS/check_safety.py" $TARGETS
python3 "$SCRIPTS/check_recipes.py" $TARGETS
bash "$SCRIPTS/check_checkmake.sh" $TARGETS
bash "$SCRIPTS/check_size.sh" $TARGETS
Each script emits a JSON array of envelopes. recommended_changes is canonical — copy through verbatim.
Script-to-rules map (29 Tier-1 rule_ids):
| Script | rule_ids | Severity |
|---|
check_secrets.py | secret | fail |
check_structure.py | shell-pin, shellflags | fail |
check_structure.py | warn-undefined, no-builtin-rules, delete-on-error, default-goal, header-comment | warn |
check_phony.py | phony-coverage | warn |
check_help.py | help-target, help-auto, help-desc | warn |
check_indent.py | tab-indent | fail |
check_naming.py | target-name, helper-prefix | warn |
check_variables.py | assignment-op, top-level-shell | warn |
check_safety.py | unguarded-rm, sudo, global-install, curl-pipe | fail |
check_safety.py | destructive-guard | warn |
check_recipes.py | literal-make, at-discipline, or-true-guard, recipe-length | warn |
check_checkmake.sh | checkmake | warn |
check_size.sh | size, line-length | warn |
The previously-INFO helper-prefix rule is remapped to warn (the pattern has no INFO).
Tier-2 exclusion list. Any FAIL in secret, shell-pin, shellflags, tab-indent, unguarded-rm, sudo, global-install, or curl-pipe excludes the Makefile from Tier-2.
Missing-tool degradation. check_checkmake.sh emits an envelope with overall_status: inapplicable and exits 0 when checkmake is absent. Other scripts continue.
3. Tier-2 Judgment Dimensions
For each Makefile that passed the Tier-2 exclusion gate, evaluate against the 7 judgment rules at references/check-*.md:
Evaluator policy: see check-skill-pattern.md §Evaluator policy. Read all 7 rule files first, then evaluate the Makefile in one LLM call.
4. Tier-3 Cross-Makefile Collision
Evaluate against check-collision.md. For multi-Makefile scope (Makefile + sibling *.mk files), surface duplicate .PHONY lists, divergent SHELL pins, or competing help definitions as warn. Single-Makefile scope returns inapplicable.
5. Report
Merge findings from all 3 tiers into a unified table:
| Tier | rule_id | Location | Status | Reasoning |
|------|---------|----------|--------|-----------|
Sort: fail before warn before inapplicable; Tier-1 before Tier-2 before Tier-3 within severity. Each Recommendation: line copies through recommended_changes verbatim.
6. Opt-In Repair Loop
Ask once: "Apply fixes? Enter y (all), n (skip), or comma-separated numbers."
For each selected finding:
- Direct edit —
SHELL pin, .SHELLFLAGS, missing .PHONY entry, tab-indent fix, help-target awk parser. Show diff; write on confirmation.
- Routed to another skill — substantial rewrites →
/build:build-makefile.
- Tier-2/3 judgment — ask the user; rewrite the section; show diff.
After each fix, re-run the relevant Tier-1 script.
Anti-Pattern Guards
- Per-dimension LLM call. Collapse into one locked-rubric call per Makefile.
- LLM-evaluating format compliance. SHELL pin,
.PHONY membership, tab-indent — handle deterministically in Tier-1.
- Ambiguous compliance reported as PASS. Surface as WARN.
- Bulk-applying fixes. Per-finding confirmation required.
- Re-evaluating scripted rules in Tier-2. Trust the
pass envelope.
- Suppressing the inapplicable envelope. When
checkmake is absent, the corresponding envelope emits inapplicable — surface it.
- Embellishing scripts'
recommended_changes. Copy through; do not paraphrase.
- Auditing recursively. Top-level Makefiles + sibling
*.mk only; recursive multi-module builds are out of scope.
Key Instructions
- Run Tier-1 deterministic checks first; gate LLM evaluation on structural validity.
- The
check_checkmake.sh wrapper gracefully degrades to inapplicable when checkmake is absent.
- Recovery: read-only outside the Repair Loop.
Handoff
Chainable to: /build:build-makefile (rebuild non-compliant Makefile from scratch).