Skip to content

T-XPG7-validator-skill-examples-no-pipe-tail

Status: closed/superseded · Impact: low · Complexity: small

Auto-generated from a /sdlc:task-work post-mortem. Review and promote to ready before picking up.

Skill prose that shows validate_frontmatter.py | tail -... masks the validator’s exit code with tail’s. Any skill that gates on the validator behaves as if validation passed even when it didn’t. Removing the pipe (or making the gating explicit) prevents silent validator regressions like the one observed in T-T5RB-consolidate-task-status-enum.

“the validator’s pipe-to-tail in skill examples masks the exit code; skills that gate on the validator should invoke it without piping.”

Multiple plugin/skills/*/SKILL.md files show validator invocations piped into tail for output trimming. Bash returns the last command’s exit code on a pipeline by default, so a non-zero validator becomes a zero exit. A skill following the example pattern would proceed past a failing gate.

Every skill that gates behavior on validate_frontmatter.py invokes it without piping (or uses set -o pipefail / explicit exit-code capture). Skill prose examples either avoid the pipe entirely or flag the masking risk in-line.

  1. Grep plugin/skills/*/SKILL.md for validate_frontmatter.py.*\| and enumerate the offending occurrences.
  2. For each, either remove the pipe or restructure (e.g. write to a temp file, then tail).
  3. Add a convention section to plugin/skills/CLAUDE.md titled “Don’t pipe commands you gate on” that names the masking trap (any pipe makes Bash return the last stage’s exit code by default), points at validate_frontmatter.py as the motivating example, and prescribes the fix (omit the pipe entirely, OR write to a tempfile then tail it, OR set -o pipefail). The convention is the durable defense — fixing the call sites alone leaves the trap one paste away from returning.
  4. Optionally add a project-check rule that flags validate_frontmatter.py | patterns in SKILL.md files.
  • plugin/skills/task-ensure-ready/SKILL.md — likely caller (uncertain).
  • plugin/skills/task-define/SKILL.md — possible caller.
  • plugin/skills/task-new/SKILL.md — possible caller.
  • Other plugin/skills/*/SKILL.md flagged by the grep.
  • plugin/skills/CLAUDE.md — add the convention doc (Approach step 3).
  • .claude/skills/project-check/check_skills.py (new check, optional).
  • AC-1: grep -rEn 'validate_frontmatter\.py[^\n]*\|' plugin/skills/*/SKILL.md returns no results (or returns only patterns with set -o pipefail / explicit exit-code propagation).
  • AC-2: A skill that intentionally passes invalid frontmatter to the validator (test fixture) is observed to halt at the gate, proving the exit code propagates.
  • AC-3: plugin/skills/CLAUDE.md contains a section explaining the pipe-masking trap and the prescribed fix. The section names validate_frontmatter.py as the motivating example.
  • Rewriting the validator itself. This task is about the call sites.
  • none

Spawned by /sdlc:task-work post-mortem of T-T5RB-consolidate-task-status-enum on 2026-05-19.


← Back to Tasks