.claude-plugin/skills/ci-deprecation-enforcement/SKILL.md
# Skill: ci-deprecation-enforcement ## Overview | Field | Value | |-----------|---------------------------------------------------------------| | Date | 2026-02-20 | | Issue | #786 | | PR | #834 | | Objective | Upgrade a non-blocking CI grep warning into a
npx skillsauth add homericintelligence/projectscylla .claude-plugin/skills/ci-deprecation-enforcementInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Field | Value | |-----------|---------------------------------------------------------------| | Date | 2026-02-20 | | Issue | #786 | | PR | #834 | | Objective | Upgrade a non-blocking CI grep warning into a hard exit-1 gate | | Outcome | Success — count=0 confirmed, exit 1 added, all 2279 tests pass |
::warning:: CI grep step to a ::error:: + exit 1 enforcement gategrep -v exclusions to an existing deprecation-counting grep chainRun the existing grep chain locally and verify it returns 0:
count=$(grep -rn "SomeDeprecatedSymbol" . \
--include="*.py" \
--exclude-dir=".pixi" \
| grep -v "definition_file.py" \
| grep -v "# deprecated" \
| grep -v "test_file.py" \
| wc -l)
echo "$count"
If count > 0, identify each hit and decide whether it is a legitimate caller
(must be removed first) or a safe reference (add a grep -v exclusion).
Two categories of false positives in this session:
Re-export files (__init__.py) — the symbol is re-exported for backward
compatibility but no new code should import it directly. Exclude by path:
| grep -v "scylla/core/__init__.py" \
Docstring "See also" mentions — legacy docs list the deprecated name with
(deprecated) in parentheses. These are informational, not callers. Exclude
by inline annotation:
| grep -v "(deprecated)" \
Pattern in the source that triggers this:
# For other types in the hierarchy, see:
# - BaseExecutionInfo (core/results.py) - Legacy dataclass (deprecated)
The existing grep -v "# deprecated" filter catches standalone comment lines
(# deprecated) but NOT inline annotations like (deprecated). Both filters
are needed.
- name: Enforce no new deprecated BaseExecutionInfo usage
run: |
count=$(grep -rn "BaseExecutionInfo" . \
--include="*.py" \
--exclude-dir=".pixi" \
| grep -v "scylla/core/results.py" \
| grep -v "scylla/core/__init__.py" \
| grep -v "# deprecated" \
| grep -v "(deprecated)" \
| grep -v "test_results.py" \
| wc -l)
echo "BaseExecutionInfo usage count (excluding definition, re-export, and tests): $count"
if [ "$count" -gt "0" ]; then
echo "::error::Found $count usages of deprecated BaseExecutionInfo — remove before merging"
grep -rn "BaseExecutionInfo" . --include="*.py" --exclude-dir=".pixi" \
| grep -v "scylla/core/results.py" \
| grep -v "scylla/core/__init__.py" \
| grep -v "# deprecated" \
| grep -v "(deprecated)" \
| grep -v "test_results.py"
exit 1
fi
Key changes from the warning step:
::warning:: → ::error::exit 1 inside the if blockpixi run python -m pytest tests/ -v
This CI change touches only .github/workflows/test.yml — no Python source
changes are needed and no new tests are required.
grep -v "# deprecated" to catch docstring mentionsThe existing filter grep -v "# deprecated" only strips lines that literally
start with # deprecated (Python comment prefix). It does not match lines like:
- BaseExecutionInfo (core/results.py) - Legacy dataclass (deprecated)
These are inside docstrings and use (deprecated) in parentheses at the end
of the line. A separate grep -v "(deprecated)" filter is required.
Symptom: count was 2 instead of 0 after adding __init__.py exclusion.
grep output showed the two docstring lines in runner.py:70 and result.py:21.
| Metric | Value |
|-----------------|--------------------------------------------|
| Tests total | 2279 |
| Coverage | 73.58% (threshold: 73%) |
| Count after fix | 0 |
| Files changed | 1 (.github/workflows/test.yml) |
| New exclusions | scylla/core/__init__.py, (deprecated) |
grep -v exclusions for re-exports and docstring annotations::warning:: to ::error::exit 1 inside the if blockdevelopment
# Skill: docs-status-fix ## Overview | Field | Value | |------------|----------------------------------------------------| | Date | 2026-02-19 | | Category | documentation | | Objective | Fix stale "Current Status" in CLAUDE.md | | Issue | #753 | | PR | #810
tools
# Skill: preflight-closing-issues-fix ## Overview | Field | Value | |-------|-------| | Date | 2026-02-21 | | Issue | #802 | | PR | #912 | | Category | tooling | | Objective | Fix `preflight_check.sh` Check 3 false positives caused by free-text PR search matching issue numbers in unrelated PR titles/bodies | | Outcome | Success — 6 bash tests pass, all pre-commit hooks green, PR created with auto-merge | ## When to Use Trigger this skill when: - A preflight/guard script uses `gh pr list --s
tools
# Preflight Check Skill Propagation ## Overview | Field | Value | |-------|-------| | Date | 2026-02-21 | | Issue | #803 | | Objective | Add preflight check to `worktree-create` skill so developers bypassing `gh-implement-issue` still run the 6-check safety gate | | Outcome | Success — PR #917 created, auto-merge enabled | | Files Changed | `tests/claude-code/shared/skills/worktree/worktree-create/SKILL.md` | ## When to Use Use this pattern when: - A safety/quality gate exists in one entry-
tools
# Orphan Config Detection ## Overview | Field | Value | |------------|-----------------------------------------------------------------| | Date | 2026-02-20 | | Issue | #777 | | PR | #824 | | Objective | Warn when a `config/models/*.yaml` file