
Shared Patterns
- 93 installs
- 325 repo stars
- Updated August 2, 2026
- athola/claude-night-market
Compose validation, workflow, and error-handling patterns consistently when authoring or refactoring agent skills and hooks.
About
Shared Patterns is a journey-wide meta skill for builders who maintain Claude-style skills and hooks in a modular repo layout. It explains how to combine validation, workflow execution, and error-handling surfaces without duplicating logic or creating circular references between markdown modules. The documented standard order—validate required fields first, execute checklist or workflow steps second, and wrap writes and side effects in structured failure paths third—gives agents a repeatable integration recipe. Selection heuristics help choose among overlapping patterns when several modules seem to fit the same hook. Relative-path cross-links (for example from creation.md to validation-patterns.md) support progressive loading during authoring sessions. Solo developers shipping agent bundles use it whenever they extend SKILL.md libraries, debug composition bugs, or align new skills with an existing night-market pattern set. It does not replace domain skills; it keeps your skill factory consistent from Idea through Operate whenever you touch agent infrastructure.
- Standard three-step composition order: validate input, run workflow logic, wrap with fail-safe error handling.
- Pattern selection heuristics when multiple shared patterns look applicable.
- One-directional cross-module reference table (creation, editing, troubleshooting → sibling pattern docs).
- Multi-pattern integration guidance to avoid duplication across skills and hooks.
- Concrete Python-style composition example tying validation-patterns, workflow-patterns, and error-handling.
Shared Patterns by the numbers
- 93 all-time installs (skills.sh)
- Ranked #267 of 782 Skill Development skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/athola/claude-night-market --skill shared-patternsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 93 |
|---|---|
| repo stars | ★ 325 |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 2, 2026 |
| Repository | athola/claude-night-market ↗ |
What it does
Compose validation, workflow, and error-handling patterns consistently when authoring or refactoring agent skills and hooks.
Files
Shared Patterns
Reusable patterns and templates for skill and hook development.
Purpose
This skill provides shared patterns that are referenced by other skills in the abstract plugin. It follows DRY principles by centralizing common patterns.
Pattern Categories
Validation Patterns
See modules/validation-patterns.md for:
- Input validation templates
- Schema validation patterns
- Error reporting formats
Error Handling
See modules/error-handling.md for:
- Exception hierarchies
- Error message formatting
- Recovery strategies
Testing Templates
See modules/testing-templates.md for:
- Unit test scaffolding
- Integration test patterns
- Mock fixtures
Workflow Patterns
See modules/workflow-patterns.md for:
- Checklist templates
- Feedback loop patterns
- Progressive disclosure structures
Usage
Reference these patterns from other skills:
For validation patterns, see the `shared-patterns` skill's
[validation-patterns](../shared-patterns/modules/validation-patterns.md) module.Verification: Run the command with --help flag to verify availability.
Advanced Pattern Composition
How to combine multiple shared patterns in a single skill or hook without duplication, and how to choose between patterns when several look applicable.
Multi-Pattern Integration
Most non-trivial skills use two or more patterns from this skill in combination. The composition order matters: validation runs before workflow execution, error handling wraps both, and tests exercise the composed surface.
Standard Composition Order
# 1. Validate input first (validation-patterns)
result = validate_required_fields(data, ["name", "description"])
if result:
raise ValidationError(
f"Missing fields: {result}", code="E001"
)
# 2. Run workflow logic (workflow-patterns)
output = process_with_checklist(data)
# 3. Wrap the whole thing in fail-safe handling (error-handling)
try:
write_output(output)
except StructureError as exc:
logger.error("Write failed", extra={"code": "E003"})
return fail_safe_result(data, exc)Cross-Module References
Each module can reference siblings by relative path:
| From | To | Relative Path |
|---|---|---|
creation.md | validation-patterns.md | ./validation-patterns.md |
editing.md | error-handling.md | ./error-handling.md |
troubleshooting.md | workflow-patterns.md | ./workflow-patterns.md |
Keep references one-directional where possible. Cycles between modules make the skill harder to load progressively.
Pattern Selection Heuristics
When two patterns overlap, pick the one whose primary axis matches your failure mode.
| Failure Mode | Primary Axis | Pattern |
|---|---|---|
| Bad input shape | data | validation-patterns |
| Operation fails partway | control flow | error-handling |
| Multi-step process needs ordering | workflow | workflow-patterns |
| Need to verify behavior | observation | testing-templates |
If two axes apply, compose them rather than picking one. A skill that needs both validated input and a recovery path uses validate_required_fields() (from validation-patterns) inside a try block that catches ValidationError (from error-handling).
When to Compose vs Inline
Compose a shared pattern when:
- The same logic appears in 2+ skills already
- The pattern has a stable public shape (function signature,
exception class, frontmatter field set)
- A new caller can use it without editing the source
Inline a one-off variant when:
- The skill needs a tweak that no other caller needs
- Forcing the change upstream would break existing callers
- The variant is small enough that inlining is cheaper than
documenting the divergence
Anti-Patterns
- Pattern stacking without need: Pulling in all four pattern
modules because "we might use them later". Each unused import is dead context.
- Cyclic module references: Module A points to B, B points
back to A. Progressive loaders cannot order the load.
- Silent overrides: Redefining
ValidationErrorlocally to
add a field instead of subclassing the one in error-handling.md. Callers downstream see two unrelated exception types with the same name.
- Pattern as decoration: Wrapping straight-line code in
try/except ValidationError when the code never raises ValidationError. Adds noise without catching anything.
Cross-Reference
See creation.md for extracting a new shared pattern from a recurring need, and editing.md for changing one safely.
Creating a New Shared Pattern
How to extract a reusable pattern from a recurring need, decide whether the abstraction earns its keep, and add it to this skill without breaking existing callers.
Extraction Methodology
Wait for the third occurrence before extracting. The first time you write a chunk of code, you do not know what is essential vs incidental. The second time, you guess. The third time, you have enough variation across callers to see the true shape.
Three-Strike Rule
| Occurrence | Action |
|---|---|
| First | Inline. Note the code in your head. |
| Second | Inline. Add a comment: "duplicate of X". |
| Third | Extract into a shared pattern module. |
Do not skip ahead. Premature extraction freezes the wrong abstraction and forces later callers to fight the shape.
Extraction Steps
1. List the 3+ call sites side by side. 2. Identify the parts that are identical across all sites. 3. Identify the parts that vary; these become parameters. 4. Identify the parts that are accidentally similar; leave those inline. 5. Write the extracted function with the smallest signature that covers all current callers. 6. Replace each call site with a call to the new function. 7. Run each caller's test suite.
When to Abstract
Extract a shared pattern when all of these hold:
- Three or more skills do the same thing
- The thing has a name you can defend in one sentence
- The contract (inputs, outputs, errors) is stable enough that
callers will not need it to change every release
- The cost of the extra import is less than the cost of keeping
copies in sync
Look at validation-patterns.md for an example: every skill that parses frontmatter needs validate_required_fields(). The shape is small (a dict and a list of keys), the output is a list of missing keys, and the contract has not changed.
When to Inline
Keep the code inline when any of these hold:
- Only one or two callers exist
- The "same" code in two places is doing different things at the
domain level (similar shape, different intent)
- Extracting would force the function to take many flag
parameters to handle each caller's quirks
- The shared version would be longer than the sum of the
inlined versions
A shared pattern with five boolean flags is usually two patterns wearing the same name. Split or keep inline.
Adding the Module
1. Create modules/<pattern-name>.md next to the existing modules in plugins/abstract/skills/shared-patterns/modules/. 2. Match the structure of a sibling: opening paragraph, code block with the pattern, table of variants, anti-patterns. 3. Add the module to the modules: list in SKILL.md frontmatter. 4. Add a section in the parent SKILL.md body that points to the new module under Pattern Categories. 5. Update each caller to reference the new module by relative path: ../shared-patterns/modules/<pattern-name>.md.
Anti-Patterns
- Speculative extraction: Building a shared pattern for code
that has only one caller. There is no signal yet about what varies and what is fixed.
- God module: A single
helpers.mdthat grows to hold every
shared snippet. Prefer one focused module per pattern.
- Renaming during extraction: Calling the new function
something different from what each caller called it. Forces reviewers to rebuild the mental map.
- Hidden coupling: The shared pattern reads global state
(env vars, module-level singletons) so callers cannot tell from the signature what it depends on.
Cross-Reference
See editing.md for changing a pattern after its first release, and advanced.md for composing several patterns in one skill.
Editing an Existing Shared Pattern
How to change a shared pattern without breaking the skills that depend on it. Covers versioning, backward compatibility, and caller migration.
Before You Edit
Find every caller first. A shared pattern in this skill is referenced by relative path, by Skill() call, or by Python import. Each surface needs its own search.
# Markdown references (relative path)
rg "shared-patterns/modules/<pattern-name>" plugins/
# Skill activation references
rg "Skill\(abstract:shared-patterns\)" plugins/
# Python imports (if the pattern ships code)
rg "from abstract.shared_patterns" plugins/If the pattern has more than five callers, treat the edit as a release: write down the contract change, the migration path, and the deprecation timeline before touching code.
Change Classes
| Class | Example | Backward Compat | Caller Action |
|---|---|---|---|
| Additive | New optional parameter, new error subclass | Yes | None |
| Renaming | Rename function or field | No | Update call site |
| Semantic | Same signature, different behavior | No | Re-test |
| Removal | Delete function, drop field | No | Replace or pin |
Additive changes can ship without coordination. The other three need a migration plan.
Versioning
This skill follows the parent plugin's version. Bump the parent SKILL.md version: field when a non-additive change ships.
# plugins/abstract/skills/shared-patterns/SKILL.md
---
name: shared-patterns
version: 1.9.4 # bump on non-additive edits
---For Python-shipped patterns, mirror the bump in plugins/abstract/pyproject.toml and add a changelog entry.
Backward Compatibility Tactics
Deprecation Window
Keep the old surface working for one release while pointing callers at the new one.
import warnings
def validate_required_fields(data, required, fields=None):
"""Validate required fields in a dict.
.. deprecated:: 1.9.4
``fields`` was renamed to ``required``. Pass ``required=``.
"""
if fields is not None:
warnings.warn(
"validate_required_fields(fields=) is deprecated; "
"use required= instead",
DeprecationWarning,
stacklevel=2,
)
required = fields
return [f for f in required if f not in data or not data[f]]Subclass for New Behavior
Add a new class instead of mutating the existing one when the contract changes.
class ValidationError(AbstractError):
"""Original. Keep as-is."""
class StrictValidationError(ValidationError):
"""New variant that includes a field path."""
def __init__(self, message, field_path):
super().__init__(message)
self.field_path = field_pathExisting except ValidationError blocks still catch the new class. Callers who want the new field can match the subclass.
Migration of Callers
For breaking changes, walk each caller in order:
1. Identify all callers (see "Before You Edit"). 2. Update them in a single PR or a stack, smallest first. 3. Run the caller's test suite at each step. 4. Land the new pattern and the caller updates together so no intermediate commit references a missing surface.
If callers are in multiple plugins, coordinate via the parent plugin's release notes rather than landing partial migrations.
Anti-Patterns
- Silent semantic change: Same function name, same
signature, different behavior. No warning, no version bump. Callers break in production.
- Soft delete: Removing a function but leaving the docs
pointing at it. New callers waste time before discovering it is gone.
- Forever deprecation: Marking a function deprecated and
never removing it. The deprecation loses meaning and callers ignore the warning.
- Local fork to avoid the migration: A caller copy-pastes
the old version into its own module to dodge the rename. The drift compounds at the next change.
Cross-Reference
See creation.md for adding a new pattern, and troubleshooting.md for diagnosing failures after a change.
Error Handling Patterns
Consistent error handling across skills and hooks.
Exception Hierarchy
class AbstractError(Exception):
"""Base exception for abstract plugin."""
pass
class ValidationError(AbstractError):
"""Raised when validation fails."""
def __init__(self, message: str, field: str = None, code: str = None):
self.field = field
self.code = code
super().__init__(message)
class StructureError(AbstractError):
"""Raised when file/directory structure is invalid."""
pass
class ConfigurationError(AbstractError):
"""Raised when configuration is invalid."""
passError Message Format
Structure
[LEVEL] [CODE]: Brief description
Location: file:line (if applicable)
Details: Extended explanation
Suggestion: How to fixExamples
Good:
[ERROR] E001: Missing required field 'description'
Location: skills/my-skill/SKILL.md
Details: The YAML frontmatter must include a 'description' field
Suggestion: Add 'description: <what it does and when to use it>'Bad:
Error: description missingRecovery Strategies
Fail-Safe Defaults
For hooks and validators:
def validate_with_fallback(data: dict) -> dict:
"""Validate and return result with safe defaults."""
try:
return validate_strict(data)
except ValidationError as e:
logger.warning(f"Validation failed: {e}, using defaults")
return {'valid': False, 'errors': [str(e)], 'data': data}Graceful Degradation
For optional features:
def load_optional_module(name: str) -> Module | None:
"""Load module if available, None otherwise."""
try:
return load_module(name)
except ModuleNotFound:
logger.info(f"Optional module {name} not found, skipping")
return NoneLogging Patterns
Structured Logging
import logging
logger = logging.getLogger(__name__)
# Use structured messages
logger.error("Validation failed", extra={
'field': 'description',
'code': 'E001',
'file': 'SKILL.md'
})Log Levels
| Level | Use Case |
|---|---|
| ERROR | Validation failures, missing required files |
| WARNING | Exceeded soft limits, deprecated usage |
| INFO | Normal operation, file processing |
| DEBUG | Detailed processing steps |
Testing Templates
Reusable test patterns for skills and scripts.
Unit Test Scaffold
"""Test module for [component]."""
import pytest
from pathlib import Path
# Fixtures
@pytest.fixture
def sample_skill_path(tmp_path: Path) -> Path:
"""Create a minimal valid skill for testing."""
skill_dir = tmp_path / "test-skill"
skill_dir.mkdir()
skill_md = skill_dir / "SKILL.md"
skill_md.write_text("""---
name: test-skill
description: Test skill for validation. Use when testing validation logic.
---
# Test Skill
Test content.
""")
return skill_md
@pytest.fixture
def invalid_skill_path(tmp_path: Path) -> Path:
"""Create an invalid skill for testing error handling."""
skill_dir = tmp_path / "invalid-skill"
skill_dir.mkdir()
skill_md = skill_dir / "SKILL.md"
skill_md.write_text("No frontmatter")
return skill_md
# Test classes
class TestValidation:
"""Tests for validation functionality."""
def test_valid_skill_passes(self, sample_skill_path: Path):
"""Valid skills should pass validation."""
result = validate(sample_skill_path)
assert result.is_valid
assert not result.errors
def test_invalid_skill_fails(self, invalid_skill_path: Path):
"""Invalid skills should fail with clear errors."""
result = validate(invalid_skill_path)
assert not result.is_valid
assert len(result.errors) > 0
def test_error_messages_are_helpful(self, invalid_skill_path: Path):
"""Error messages should include suggestions."""
result = validate(invalid_skill_path)
for error in result.errors:
assert error.suggestion is not NoneIntegration Test Pattern
"""Integration tests for [workflow]."""
import subprocess
from pathlib import Path
class TestWorkflow:
"""End-to-end workflow tests."""
def test_full_validation_workflow(self, skill_directory: Path):
"""Test complete validation workflow."""
# Run the validator
result = subprocess.run(
["python", "scripts/validator.py", str(skill_directory)],
capture_output=True,
text=True
)
# Check exit code
assert result.returncode == 0
# Check output
assert "Validation passed" in result.stdout
def test_workflow_with_errors(self, invalid_directory: Path):
"""Test workflow handles errors gracefully."""
result = subprocess.run(
["python", "scripts/validator.py", str(invalid_directory)],
capture_output=True,
text=True
)
# Should fail but not crash
assert result.returncode in [1, 2]
assert "error" in result.stderr.lower() or "error" in result.stdout.lower()Mock Fixtures
"""Common mock fixtures."""
import pytest
from unittest.mock import Mock, patch
@pytest.fixture
def mock_filesystem():
"""Mock filesystem operations."""
with patch('pathlib.Path.exists') as mock_exists:
with patch('pathlib.Path.read_text') as mock_read:
yield {'exists': mock_exists, 'read_text': mock_read}
@pytest.fixture
def mock_skill_data() -> dict:
"""Standard skill frontmatter for testing."""
return {
'name': 'test-skill',
'description': 'Test skill for validation. Use when testing.',
'version': '1.0.0',
'category': 'testing',
'tags': ['test', 'validation'],
}Parameterized Tests
@pytest.mark.parametrize("name,expected_valid", [
("valid-name", True),
("also-valid-123", True),
("Invalid_Name", False), # Underscore not allowed
("UPPERCASE", False), # Must be lowercase
("with spaces", False), # Spaces not allowed
("a" * 65, False), # Too long
])
def test_name_validation(name: str, expected_valid: bool):
"""Test name field validation with various inputs."""
result = validate_name(name)
assert result.is_valid == expected_validAssertion Helpers
def assert_valid_skill(skill_path: Path):
"""Assert that a skill passes all validation."""
result = validate(skill_path)
assert result.is_valid, f"Validation failed: {result.errors}"
assert not result.warnings, f"Unexpected warnings: {result.warnings}"
def assert_error_contains(result: ValidationResult, code: str):
"""Assert that result contains a specific error code."""
codes = [e.code for e in result.errors]
assert code in codes, f"Expected error {code}, got {codes}"Troubleshooting Shared-Pattern Integration
Diagnostic steps for the failures that show up when a skill or hook tries to use a pattern from this skill. Covers import paths, version mismatch, and missing exports.
First Triage
Before debugging, capture three facts:
1. The exact error message and stack trace 2. The caller's plugin and version (plugin.json or SKILL.md frontmatter) 3. The shared-patterns version in use (SKILL.md version:)
If the caller and the shared-patterns skill disagree on the plugin version, that is the bug. Skip the rest of this guide and reinstall the plugin.
# Verify versions match
rg "^version:" plugins/abstract/skills/shared-patterns/SKILL.md
rg "^version:" plugins/abstract/openpackage.ymlSymptom Index
| Symptom | Likely Cause | Section |
|---|---|---|
ModuleNotFoundError | Import path wrong | Import paths |
AttributeError: module has no attribute X | Renamed export | Missing exports |
ValidationError raised but not caught | Two ValidationError classes | Version mismatch |
| Markdown link 404 | Module path moved | Reference paths |
| Function returns unexpected shape | Semantic change | Version mismatch |
Import Paths
Patterns shipped as Python live under the parent plugin's package. The canonical import is:
from abstract.shared_patterns.validation import validate_required_fields
from abstract.shared_patterns.errors import ValidationErrorCommon mistakes:
from shared_patterns import ...(missing plugin prefix)from abstract.skills.shared_patterns import ...(using the
skill directory layout instead of the package layout)
import shared-patterns(hyphens in Python identifiers)
If the import works locally but fails in CI, check that the plugin is installed in editable mode (uv pip install -e .) in the CI environment.
Reference Paths
Markdown references use the skill module layout, not the Python package layout. From a sibling skill in the same plugin:
See ../shared-patterns/modules/error-handling.md for the
exception hierarchy.From a different plugin:
See plugins/abstract/skills/shared-patterns/modules/error-handling.mdA 404 after a recent edit usually means the file was renamed. Check git log --diff-filter=R --follow modules/<old-name>.md to find the rename.
Version Mismatch
Two copies of the same exception class break except blocks:
# In caller, imported at module load
from abstract.shared_patterns.errors import ValidationError
# Somewhere else (different version cached, vendored copy, etc)
class ValidationError(Exception): ... # different class!
try:
do_thing()
except ValidationError: # only catches one
handle()Check for duplicate definitions:
rg "class ValidationError" plugins/A single canonical definition is in plugins/abstract/skills/shared-patterns/modules/error-handling.md (reference) and the corresponding Python module. Anything else is a fork to remove.
Missing Exports
If AttributeError appears after upgrading the plugin, the export was renamed or removed. Cross-check against editing.md's "Change Classes" table:
1. Look up the symbol in the current error-handling.md, validation-patterns.md, etc. 2. If absent, search recent commits to the modules directory: git log -p plugins/abstract/skills/shared-patterns/modules/ 3. Find the deprecation note or migration instruction in the commit message. 4. Update the caller per the documented migration.
If no migration note exists, the change was undocumented; file an issue against the skill before working around it.
Diagnostic Snippet
Drop this into a caller to print which version of a shared symbol is in use:
import inspect
from abstract.shared_patterns.errors import ValidationError
print("ValidationError defined at:",
inspect.getfile(ValidationError))
print("ValidationError MRO:",
[c.__name__ for c in ValidationError.__mro__])If the file path is unexpected (e.g. a .venv cache, a vendored copy), that is the source of the mismatch.
Anti-Patterns
- Catch-all suppression: Wrapping the integration in
except Exception: pass to silence the error. The bug reappears later in a worse place.
- Pinning forever: Pinning the plugin to an old version to
avoid the migration. Locks the caller out of unrelated fixes.
- Patching the shared pattern in place: Editing
error-handling.md in plugins/abstract/... from a caller plugin to make a test pass. Other callers see the change next time they update.
Cross-Reference
See editing.md for the migration patterns referenced above and creation.md for when a new pattern (rather than a fix) is the right answer.
Validation Patterns
Reusable validation patterns for skills and hooks.
Frontmatter Validation
Required Fields Check
def validate_required_fields(data: dict, required: list[str]) -> list[str]:
"""Return list of missing required fields."""
return [field for field in required if field not in data or not data[field]]Field Constraints
| Field | Constraint | Validation |
|---|---|---|
| name | ≤64 chars, kebab-case | re.match(r'^[a-z0-9-]+$', name) and len(name) <= 64 |
| description | ≤1024 chars, non-empty | 0 < len(desc) <= 1024 |
| version | semver format | re.match(r'^\d+\.\d+\.\d+$', version) |
Third-Person Voice Check
FIRST_PERSON = ['I ', 'I\'m', 'my ', 'we ', 'our ']
SECOND_PERSON = ['you ', 'your ', 'you\'re']
def is_third_person(text: str) -> bool:
"""Check if text uses third-person voice."""
text_lower = text.lower()
for phrase in FIRST_PERSON + SECOND_PERSON:
if phrase.lower() in text_lower:
return False
return TrueStructure Validation
File Existence Check
from pathlib import Path
def validate_references(skill_path: Path, references: list[str]) -> dict:
"""Validate that referenced files exist."""
results = {'valid': [], 'missing': []}
for ref in references:
ref_path = skill_path.parent / ref
if ref_path.exists():
results['valid'].append(ref)
else:
results['missing'].append(ref)
return resultsLine Count Check
def check_line_count(file_path: Path, max_lines: int = 500) -> tuple[int, bool]:
"""Return (line_count, is_over_limit)."""
with open(file_path) as f:
lines = sum(1 for _ in f)
return lines, lines > max_linesError Reporting Format
Structured Report
@dataclass
class ValidationResult:
level: str # 'error', 'warning', 'info'
code: str # 'E001', 'W001', etc.
message: str
location: str # file:line or just file
suggestion: str | None = None
def format_result(result: ValidationResult) -> str:
icon = {'error': 'X', 'warning': '!', 'info': 'i'}[result.level]
msg = f"{icon} [{result.code}] {result.message}"
if result.location:
msg += f" ({result.location})"
if result.suggestion:
msg += f"\n → {result.suggestion}"
return msgError Codes
| Code | Level | Description |
|---|---|---|
| E001 | error | Missing required field |
| E002 | error | Invalid field format |
| E003 | error | Referenced file not found |
| W001 | warning | Line count exceeds limit |
| W002 | warning | Non-third-person voice detected |
| W003 | warning | Missing recommended field |
Exit Codes
| Code | Meaning |
|---|---|
| 0 | All checks passed |
| 1 | Warnings present, but valid |
| 2 | Errors found, invalid |
| 3 | Critical errors, cannot proceed |
Workflow Patterns
Reusable workflow structures for skills.
Checklist Template
Copyable Checklist Format
Copy this checklist and track your progress:
Task Progress:
- [ ] Step 1: [Action]
- [ ] Step 2: [Action]
- [ ] Step 3: [Action]
- [ ] Step 4: [Action]
- [ ] Step 5: [Verification]
**Step 1: [Action]**
[Detailed instructions]
**Step 2: [Action]**
[Detailed instructions]
...Checklist Best Practices
1. Keep steps atomic - Each step should be one action 2. Include verification - Last step should verify success 3. Order matters - Steps should be sequential dependencies 4. Be specific - Include exact commands or actions
Feedback Loop Pattern
Validate-Fix-Repeat
## Validation Loop
1. Run validation:python scripts/validate.py path/to/target
2. If errors found:
- Review error messages
- Fix each issue
- **Return to step 1**
3. Only proceed when validation passes
4. [Next phase of workflow]With Exit Conditions
## Review Loop
Repeat until all criteria met:
1. Run analysis
2. Check results against criteria:
- [ ] All tests pass
- [ ] No security issues
- [ ] Performance within limits
3. If any criterion fails:
- Fix the specific issue
- Return to step 1
4. Proceed when all criteria passProgressive Disclosure Structure
Overview → Details Pattern
# [Skill Name]
## Quick Start
[20-30 lines of essential usage]
## Common Tasks
### Task 1
[Brief description and command]
### Task 2
[Brief description and command]
## Advanced Usage
For detailed patterns, see [modules/advanced.md](modules/advanced.md)
## Troubleshooting
For common issues, see [modules/troubleshooting.md](modules/troubleshooting.md)Conditional Loading
## Feature Selection
Choose your path:
**Creating new content?**
→ Follow the [creation workflow](modules/creation.md)
**Modifying existing content?**
→ Follow the [editing workflow](modules/editing.md)
**Troubleshooting issues?**
→ Check [troubleshooting](modules/troubleshooting.md)Decision Flowchart Template
Text-Based Decision Tree
## Decision Guide
Start here ↓
**Is this a new skill?**
├── Yes → Go to "Creating Skills"
└── No ↓
**Is this modifying an existing skill?**
├── Yes → Go to "Editing Skills"
└── No ↓
**Is this evaluating skills?**
├── Yes → Use `skills-eval`
└── No → Describe your goalTable-Based Decisions
| Condition | Action |
|---|---|
| New skill needed | Use skill-authoring |
| Skill needs evaluation | Use skills-eval |
| Hook development | Use hook-authoring |
| Plugin validation | Use validate-plugin |
Phase-Based Workflow
TDD Phases Template
## Phase 1: RED (Baseline)
**Goal**: Document current behavior without the skill
1. [ ] Create 3+ test scenarios
2. [ ] Run scenarios without skill
3. [ ] Document failures verbatim
4. [ ] Note rationalization patterns
**Exit criteria**: Baseline documented
---
## Phase 2: GREEN (Implementation)
**Goal**: Create minimal skill that addresses failures
1. [ ] Write SKILL.md addressing failures
2. [ ] Test with skill present
3. [ ] Verify improvement
**Exit criteria**: Skill addresses baseline failures
---
## Phase 3: REFACTOR (Bulletproof)
**Goal**: Close loopholes and strengthen
1. [ ] Identify new rationalizations
2. [ ] Add explicit counters
3. [ ] Create rationalization table
4. [ ] Re-test until bulletproof
**Exit criteria**: No bypass patterns foundError Recovery Pattern
## Error Handling
If you encounter an error:
1. **Read the error message carefully**
- Note the error code
- Note the location (file:line)
2. **Check common causes**:
| Error | Likely Cause | Fix |
|-------|--------------|-----|
| E001 | Missing field | Add required field |
| E002 | Invalid format | Check field constraints |
| W001 | File too long | Split into modules |
3. **Apply the fix**
4. **Re-run validation**
5. If error persists, check [troubleshooting](modules/troubleshooting.md)Related skills
FAQ
Is Shared Patterns safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.