
Impl Standards
- 116 installs
- 62 repo stars
- Updated August 3, 2026
- terrylica/cc-skills
Use impl-standards for development tasks
About
impl-standards: A skill for development. This provides functionality for development workflows.
- impl-standards
Impl Standards by the numbers
- 116 all-time installs (skills.sh)
- Ranked #2,887 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/terrylica/cc-skills --skill impl-standardsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 116 |
|---|---|
| repo stars | ★ 62 |
| Last updated | August 3, 2026 |
| Repository | terrylica/cc-skills ↗ |
What it does
Use impl-standards for development tasks
Files
Implementation Standards
Apply these standards during implementation to ensure consistent, maintainable code.
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
When to Use This Skill
- During
/itp:goPhase 1 - When writing new production code
- User mentions "error handling", "constants", "magic numbers", "progress logging", "SSoT", "dependency injection", "config singleton"
- Before release to verify code quality
Quick Reference
| Standard | Rule |
|---|---|
| Errors | Raise + propagate; no fallback/default/retry/silent |
| Constants | Abstract magic numbers into semantic, version-agnostic dynamic constants |
| SSoT/DI | Config singleton → None-default + resolver → entry-point validation |
| Dependencies | Prefer OSS libs over custom code; no backward-compatibility needed |
| Progress | Operations >1min: log status every 15-60s |
| Logs | logs/{adr-id}-YYYYMMDD_HHMMSS.log (nohup) |
| Metadata | Optional: catalog-info.yaml for service discovery |
---
Error Handling
Core Rule: Raise + propagate; no fallback/default/retry/silent
# ✅ Correct - raise with context
def fetch_data(url: str) -> dict:
response = requests.get(url)
if response.status_code != 200:
raise APIError(f"Failed to fetch {url}: {response.status_code}")
return response.json()
# ❌ Wrong - silent catch
try:
result = fetch_data()
except Exception:
pass # Error hiddenSee Error Handling Reference for detailed patterns.
---
Constants Management
Core Rule: Abstract magic numbers into semantic constants
# ✅ Correct - named constant
DEFAULT_API_TIMEOUT_SECONDS = 30
response = requests.get(url, timeout=DEFAULT_API_TIMEOUT_SECONDS)
# ❌ Wrong - magic number
response = requests.get(url, timeout=30)See Constants Management Reference for patterns.
---
Progress Logging
For operations taking more than 1 minute, log status every 15-60 seconds:
import logging
from datetime import datetime
logger = logging.getLogger(__name__)
def long_operation(items: list) -> None:
total = len(items)
last_log = datetime.now()
for i, item in enumerate(items):
process(item)
# Log every 30 seconds
if (datetime.now() - last_log).seconds >= 30:
logger.info(f"Progress: {i+1}/{total} ({100*(i+1)//total}%)")
last_log = datetime.now()
logger.info(f"Completed: {total} items processed")---
Log File Convention
Save logs to: logs/{adr-id}-YYYYMMDD_HHMMSS.log
# Running with nohup
nohup python script.py > logs/2025-12-01-my-feature-20251201_143022.log 2>&1 &---
---
Data Processing
Core Rule: Prefer Polars over Pandas for dataframe operations.
| Scenario | Recommendation |
|---|---|
| New data pipelines | Use Polars (30x faster, lazy eval) |
| ML feature eng | Polars → Arrow → NumPy (zero-copy) |
| MLflow logging | Pandas OK (add exception comment) |
| Legacy code fixes | Keep existing library |
Exception mechanism: Add at file top:
# polars-exception: MLflow requires Pandas DataFrames
import pandas as pdSee ml-data-pipeline-architecture for decision tree and benchmarks.
---
Related Skills
| Skill | Purpose |
|---|---|
| `adr-code-traceability` | Add ADR references to code |
| `code-hardcode-audit` | Detect hardcoded values before release |
| `ml-data-pipeline-architecture` | Polars/Arrow efficiency patterns |
---
Reference Documentation
- Error Handling - Raise + propagate patterns
- Constants Management - Magic number abstraction
- SSoT / Dependency Injection - Config singleton → None-default → resolver chain
---
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Silent failures | Bare except blocks | Catch specific exceptions, log or re-raise |
| Magic numbers in code | Missing constants | Extract to named constants with context |
| Error swallowed | except: pass pattern | Log error before continuing or re-raise |
| Type errors at runtime | Missing validation | Add input validation at boundaries |
| Config not loading | Hardcoded paths | Use environment variables with defaults |
Post-Execution Reflection
After this skill completes, check before closing:
1. Did the command succeed? — If not, fix the instruction or error table that caused the failure. 2. Did parameters or output change? — If the underlying tool's interface drifted, update Usage examples and Parameters table to match. 3. Was a workaround needed? — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround.
Only update if the issue is real and reproducible — not speculative.
Skill: Implement Plan Engineering Standards
Constants Management
Core principle: Abstract magic numbers into semantic, version-agnostic dynamic constants
---
The Rule
Replace hardcoded values with:
1. Named constants with semantic meaning 2. Configuration loaded from files/environment 3. Dynamic values computed at runtime when appropriate
---
Magic Numbers to Avoid
| Category | Bad | Good |
|---|---|---|
| Timeouts | timeout=30 | timeout=DEFAULT_API_TIMEOUT_SECONDS |
| Limits | if len(items) > 100: | if len(items) > MAX_BATCH_SIZE: |
| Ports | port=8080 | port=config.server_port |
| Thresholds | if ratio < 0.7: | if ratio < MIN_SUCCESS_RATIO: |
| Sizes | chunk_size=1024 | chunk_size=BUFFER_SIZE_BYTES |
---
Correct Patterns
Named Constants
# ✅ Semantic names at module level
DEFAULT_API_TIMEOUT_SECONDS = 30
MAX_RETRY_ATTEMPTS = 3
MIN_PASSWORD_LENGTH = 12
BUFFER_SIZE_BYTES = 4096
def fetch_data(url: str) -> dict:
return requests.get(url, timeout=DEFAULT_API_TIMEOUT_SECONDS).json()Configuration Objects
# ✅ Configuration from environment/files
@dataclass
class AppConfig:
api_timeout: int = field(default_factory=lambda: int(os.getenv("API_TIMEOUT", "30")))
max_batch_size: int = field(default_factory=lambda: int(os.getenv("MAX_BATCH_SIZE", "100")))
server_port: int = field(default_factory=lambda: int(os.getenv("PORT", "8080")))
config = AppConfig()Dynamic Constants
# ✅ Computed at runtime
from importlib.metadata import version
PACKAGE_VERSION = version("mypackage") # Not hardcoded "1.2.3"
# ✅ Platform-specific
import multiprocessing
DEFAULT_WORKERS = multiprocessing.cpu_count()---
Version Strings
Never hardcode version strings. Use runtime discovery:
# ❌ Bad - hardcoded
VERSION = "1.2.3"
# ✅ Good - dynamic
from importlib.metadata import version
__version__ = version("mypackage")For version management, delegate to the repo's mise release pipeline (mise run release:full).
---
Hardcode Detection
Before release, audit for hardcoded values:
# Requires CLAUDE_PLUGIN_ROOT to be set (available in plugin context)
# For manual runs, set to your plugin installation directory
uv run --script "$CLAUDE_PLUGIN_ROOT/skills/code-hardcode-audit/scripts/audit_hardcodes.py" -- src/See `code-hardcode-audit` skill for details.
---
Exceptions
Some hardcoded values are acceptable:
- Mathematical constants -
PI = 3.14159,E = 2.71828 - Protocol constants - HTTP status codes, well-known ports for standard services
- Array indices - When semantically clear (e.g.,
row[0]for first element)
The test: Would this value ever need to change? If yes, make it configurable.
---
Organization
Group constants by domain:
# constants.py
# Timing
DEFAULT_API_TIMEOUT_SECONDS = 30
DEFAULT_CACHE_TTL_SECONDS = 3600
HEALTH_CHECK_INTERVAL_SECONDS = 60
# Limits
MAX_BATCH_SIZE = 100
MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024 # 10MB
MAX_CONCURRENT_REQUESTS = 10
# Feature flags (load from config in production)
ENABLE_DEBUG_LOGGING = os.getenv("DEBUG", "").lower() == "true"Skill: Implement Plan Engineering Standards
Error Handling Standards
Core principle: Raise + propagate; no fallback/default/retry/silent
---
The Rule
When an error occurs, the code must:
1. Raise an exception with clear context 2. Propagate the error up the call stack 3. Fail visibly so the issue can be identified and fixed
---
Forbidden Patterns
| Pattern | Why Forbidden |
|---|---|
| Silent catch | Hides failures, causes debugging nightmares |
| Default values on error | Masks real issues with fake data |
| Automatic retry | Hides intermittent failures, wastes resources |
| Fallback to alternative | Unclear which path executed, hard to debug |
Bad Examples
# ❌ Silent catch
try:
result = fetch_data()
except Exception:
pass # Error silently ignored
# ❌ Default on error
try:
config = load_config()
except FileNotFoundError:
config = {} # Hides missing config
# ❌ Auto-retry
for _ in range(3):
try:
return api_call()
except:
time.sleep(1)
return None # Silent failure after retries
# ❌ Fallback
try:
return primary_service()
except:
return backup_service() # Which one ran? Unknown.---
Correct Patterns
# ✅ Raise with context
def fetch_data(url: str) -> dict:
response = requests.get(url)
if response.status_code != 200:
raise APIError(f"Failed to fetch {url}: {response.status_code}")
return response.json()
# ✅ Propagate with additional context
def process_user(user_id: str) -> User:
try:
data = fetch_user_data(user_id)
except APIError as e:
raise ProcessingError(f"Cannot process user {user_id}") from e
return User.from_dict(data)
# ✅ Let caller handle
def main():
try:
result = process_user("123")
except ProcessingError as e:
logger.error(f"User processing failed: {e}")
sys.exit(1) # Visible failure---
When Exceptions Are Appropriate
Errors should be raised for:
- Invalid input - Data that doesn't meet requirements
- Missing resources - Files, services, configs that must exist
- API failures - Network errors, unexpected responses
- State violations - Invariants that are broken
---
Logging Before Raising
When raising, log the error with context:
def connect_database(config: DBConfig) -> Connection:
try:
conn = create_connection(config.url)
except ConnectionError as e:
logger.error(f"Database connection failed: {config.url}", exc_info=True)
raise DatabaseError(f"Cannot connect to database") from e
return conn---
Rationale
This approach:
1. Surfaces problems immediately - No hidden failures 2. Preserves error context - Full stack trace available 3. Simplifies debugging - Error location is clear 4. Forces explicit handling - Callers must decide how to respond
Evolution Log
Convention: Reverse chronological order (newest on top, oldest at bottom). Prepend new entries.
---
2026-02-26: Initial Evolution Log
Status: Skill is in use and maintained. Track improvements here.
Purpose
This evolution log tracks updates to the skill. Each entry should note:
- What changed (content, structure, tooling)
- Why it changed (bug fix, feature request, best practice)
- Files affected
How to Use
1. When updating SKILL.md or references, add an entry here with the date 2. Keep entries reverse-chronological (newest first) 3. Link to ADRs or GitHub issues when relevant 4. Reference specific line changes when helpful
---
Skill: Implement Plan Engineering Standards
SSoT / Dependency Injection Patterns
Core principle: Centralize defaults in one config object, inject via None-default parameters, resolve at call time
---
Beyond Constants
Constants management covers named constants and configuration objects. This document extends that to the full resolution chain — eliminating scattered defaults that drift across files.
The problem: ouroboros_mode="year" hardcoded in 10+ function signatures across 6 files. Changing the system-wide default requires editing every file.
The solution: One env var change propagates everywhere.
---
The 5-Step Resolution Chain
ENV VAR → CONFIG SINGLETON → RESOLVER HELPER → NONE-DEFAULT → ENTRY-POINT VALIDATION| Step | What | Why |
|---|---|---|
| 1. Env var | OUROBOROS_MODE=year | External configuration, no code changes |
| 2. Config singleton | Settings.ouroboros_mode | One validated object, fail-fast startup |
| 3. Resolver helper | resolve_mode(mode) | None → config lookup, value → passthrough |
| 4. None-default params | `def foo(mode: str \ | None = None)` |
| 5. Entry-point validation | Validate at public API boundaries | Catch bad inputs early, not deep in logic |
---
Language-Specific Examples
Python (Settings frozen dataclass)
# ✅ Config singleton
from dataclasses import dataclass
import os
@dataclass(frozen=True)
class Settings:
ouroboros_mode: str = os.getenv("OUROBOROS_MODE", "year") # SSoT-OK: config entrypoint
batch_size: int = int(os.getenv("BATCH_SIZE", "64"))
@classmethod
def get(cls) -> "Settings":
if not hasattr(cls, "_instance"):
cls._instance = cls()
return cls._instance
# ✅ Resolver helper
def resolve_mode(mode: str | None = None) -> str:
return mode if mode is not None else Settings.get().ouroboros_mode
# ✅ None-default parameter
def process_data(mode: str | None = None):
effective_mode = resolve_mode(mode)
# ...TypeScript (config object)
// ✅ Config singleton
const config = {
ouroboros_mode: process.env.OUROBOROS_MODE ?? "year", // SSoT-OK: config entrypoint
batchSize: parseInt(process.env.BATCH_SIZE ?? "64", 10),
} as const;
// ✅ Resolver + None-default
function processData(mode?: string) {
const effectiveMode = mode ?? config.ouroboros_mode;
// ...
}Rust (Config + Default trait)
// ✅ Config struct with Default
#[derive(Debug)]
struct Config {
ouroboros_mode: String,
batch_size: usize,
}
impl Default for Config {
fn default() -> Self {
Self {
ouroboros_mode: std::env::var("OUROBOROS_MODE") // SSoT-OK: config entrypoint
.unwrap_or_else(|_| "year".to_string()),
batch_size: std::env::var("BATCH_SIZE")
.ok().and_then(|s| s.parse().ok()).unwrap_or(64),
}
}
}
// ✅ Option parameter + config resolution
fn process_data(mode: Option<&str>, config: &Config) {
let effective_mode = mode.unwrap_or(&config.ouroboros_mode);
// ...
}Go (functional options)
// ✅ Config struct
type Config struct {
OuroborosMode string
BatchSize int
}
func NewConfig() Config {
mode := os.Getenv("OUROBOROS_MODE") // SSoT-OK: config entrypoint
if mode == "" {
mode = "year"
}
return Config{OuroborosMode: mode, BatchSize: 64}
}
// ✅ Functional option pattern
type Option func(*processor)
func WithMode(mode string) Option {
return func(p *processor) { p.mode = mode }
}---
Anti-Patterns Detected by ast-grep
| Anti-Pattern | ast-grep Rule | Fix |
|---|---|---|
def foo(mode: str = "year") | hardcoded-string-default-python | `def foo(mode: str \ |
def foo(size: int = 64) | hardcoded-int-default-python | `def foo(size: int \ |
os.environ.get("VAR") | direct-env-access-python | Settings.get().var |
process.env.VAR | direct-process-env-typescript | config.var |
env::var("VAR") | direct-env-var-rust | Config::default().var |
os.Getenv("VAR") | direct-os-getenv-go | config.Var |
Rules location: plugins/itp-hooks/hooks/ast-grep-ssot/rules/
---
Real-World Case Study: rangebar-py Ouroboros Migration
Before: ouroboros_mode="year" hardcoded in 10 function signatures across 6 files.
After: One Settings singleton + one resolve_ouroboros_mode() helper + None-default parameters everywhere.
Result: Changing the system-wide default from "year" to "month" = one env var: OUROBOROS_MODE=month.
| Metric | Before | After |
|---|---|---|
| Files to edit for default change | 6 | 0 (env var only) |
| Functions with hardcoded default | 10 | 0 |
| Config entrypoints | 0 | 1 (Settings) |
---
Escape Hatch
Add # SSoT-OK (Python/Rust) or // SSoT-OK (TypeScript/Go) comment to suppress ast-grep findings.
Use for legitimate config entrypoints (the one place that reads env vars), mathematical constants, or protocol-defined values.
---
Hierarchical Lookup Pattern
For systems with multiple override levels:
Per-item override → Registry lookup → Class default → Global fallback (with warning)def resolve_threshold(symbol: str | None = None) -> float:
"""Hierarchical lookup with warning on fallback."""
if symbol and symbol in SYMBOL_THRESHOLDS:
return SYMBOL_THRESHOLDS[symbol] # Per-item override
if symbol and symbol in THRESHOLD_REGISTRY:
return THRESHOLD_REGISTRY[symbol] # Registry lookup
if hasattr(Settings.get(), "default_threshold"):
return Settings.get().default_threshold # Class default
import warnings
warnings.warn("Using hardcoded fallback threshold")
return 0.5 # Fallback (with warning)