Applies language-agnostic and backend technical decision criteria, anti-pattern detection, debugging, and quality gates. Use when reviewing general/backend implementation choices, code smells, failures, or implementation completeness.
4k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
664
stars on the repo
on the repository, not the skill itself
Install
one command, takes just this skill from the repository
AI Developer Guide - Technical Decision Criteria and Anti-pattern Collection
Value-First Engineering
Explore broadly, then converge on the lowest-lifecycle-cost solution that delivers the required user, operator, or maintainer value while keeping the system correct and maintainable.
Resolve verified problems within confirmed scope or dependencies required for the outcome; report other findings with evidence for a scope decision.
Introduce capabilities, infrastructure, abstractions, or speculative edge-case handling when a current outcome, verified constraint, or evidence-backed material risk requires them.
Technical Anti-patterns (Red Flag Patterns)
Pause the affected decision and review the design when detecting the following patterns:
Code Quality Anti-patterns
Writing similar code 3 or more times - Violates Rule of Three
Multiple responsibilities mixed in a single file - Violates Single Responsibility Principle (SRP)
Defining same content in multiple files - Violates DRY principle
Making changes without checking dependencies - Potential for unexpected impacts
Disabling code with comments - Should use version control
"Make it work for now" thinking - Accumulation of technical debt
Patchwork implementation - Unplanned additions to existing code
Optimistic implementation of uncertain technology - Designing unknown elements assuming "it'll probably work"
Symptomatic fixes - Surface-level fixes that don't solve root causes
Unplanned large-scale changes - Lack of incremental approach
Fail-Fast Fallback Design Principles
Core Principle
Make all errors visible and traceable with full context. Prioritize primary code reliability over fallback implementations. Excessive fallback mechanisms mask errors and make debugging difficult.
Implementation Guidelines
Default Approach
Give every failure an explicit outcome: propagate it, translate it to the boundary's error contract, or recover through an accepted fallback
Make failures explicit: Errors should be visible and traceable
Preserve error context: Include original error information when re-throwing
When Fallbacks Are Acceptable
Accepted recovery contract: A requirement, Design Doc, existing boundary contract, or project policy defines why degraded behavior is preferable to failure
Business-critical continuity: When partial functionality is better than none
Graceful degradation paths: Clearly defined degraded service levels
Layer Responsibilities
Infrastructure Layer:
Preserve the original cause and operational context
Propagate, translate, or return the failure in the form required by the caller's boundary contract
Perform infrastructure-owned cleanup or retry only when that boundary owns it; business recovery decisions remain in the application layer
Application Layer:
Make business-driven error handling decisions
Implement fallbacks only when an accepted recovery contract defines the degraded outcome
Make fallback activation observable through the project's established logging, metrics, or user-visible state when diagnosis or recovery requires it
Error Masking Detection
Review Triggers (require design review):
Writing the 3rd error handler in the same feature; review whether recovery ownership is fragmented before adding it
The same failure is caught at multiple layers without a single recovery owner
Nested handlers obscure which state is committed, rolled back, or exposed
A handler converts a failure to success/default output without an observable degraded-state contract
Error handlers that return default values without logging
The third handler may remain when it covers a distinct failure mode with a documented recovery owner, state outcome, and observable signal.
Before Implementing Any Fallback:
Identify the accepted requirement, boundary contract, project policy, or Design Doc entry that defines this fallback
Document the business justification
Make activation observable at the boundary that owns diagnosis or recovery through one existing UI, log, or metric channel; when logging is that channel, log once with sensitive data redacted
Add new monitoring or alerting only when an operational requirement or project policy requires it
Pattern 3: Implementation Without Sufficient Testing
Symptom: Many bugs after implementation
Cause: Ignoring Red-Green-Refactor process
Avoidance: Start implementation with a failing test that proves the intended behavior
Pattern 4: Ignoring Technical Uncertainty
Symptom: Frequent unexpected errors when introducing new technology
Cause: Assuming "it should work according to official documentation" without prior investigation
Avoidance:
Record certainty evaluation at the beginning of task files
Certainty: low (Reason: no working examples found for this integration)
Exploratory implementation: true
Fallback: use established alternative approach
For low certainty cases, create minimal verification code first
Cause: Insufficient understanding of existing code before implementation; referencing only nearby files without verifying representativeness
Avoidance Methods:
Before implementation, always search for similar functionality (using domain, responsibility, configuration patterns as keywords)
Similar functionality found → Verify that its contract, lifecycle, and repository usage are representative; reuse or extend it when compatible, otherwise record why it is not a valid model
Similar functionality is technical debt → Repair it when it blocks the current outcome, was caused by the current change, or lies in confirmed scope; otherwise report it separately. Create an ADR when the repair requires an architectural decision
No similar functionality exists → Implement new functionality following existing design philosophy
Record all decisions and rationale in "Existing Codebase Analysis" section of Design Doc
Reference representativeness check: When adopting a pattern or dependency from nearby code, verify it is representative across the repository before adopting — nearby files alone are an insufficient basis
Quality Assurance Mechanism Awareness
Before executing quality checks, identify what quality mechanisms exist for the change area:
Primary detection: inspect the change area's file types, project manifest, and configuration to identify applicable quality tools
Check CI pipeline definitions for checks that cover the affected paths
Check for domain-specific linter or validator configurations (e.g., schema validators, API spec validators, configuration file linters)
Check for domain-specific constraints in project configuration (naming rules, length limits, format requirements)
Supplementary hint: IF task file specifies Quality Assurance Mechanisms → use them as additional hints for which domain-specific checks to look for
Include discovered domain-specific checks alongside standard quality phases below
Quality Check Workflow
Universal quality assurance phases applicable to all languages:
Phase 1: Static Analysis
Code Style Checking: Verify adherence to style guidelines
Code Formatting: Ensure consistent formatting
Unused Code Detection: Identify dead code and unused imports/variables
Static Type Checking: Verify type correctness (for statically typed languages)
Dependency Resolution: Ensure all dependencies are available and compatible
Resource Validation: Check configuration files, assets are valid
Phase 3: Testing
Implementation Feedback: During implementation, run the smallest configured tests that exercise the changed behavior
Completion Tests: Before completion, run the repository's configured test commands; include integration or E2E suites when the change crosses their boundary, test skeletons require them, or the project quality gate includes them
Test Coverage: Use coverage as a gap signal and satisfy any project-configured threshold
Phase 4: Final Quality Gate
All checks must pass before proceeding:
Zero static analysis errors
Build succeeds
All tests pass
Coverage meets project-configured threshold
Quality Check Pattern (Language-Agnostic)
Workflow:
1. Discover applicable project checks → 2. Run fast affected checks →
3. Run configured build/static gates → 4. Run boundary-relevant broader tests →
5. Run the project's final required gate
Auto-fix capabilities (when available):
- Format auto-fix
- Lint auto-fix
- Dependency/import organization
- Simple code smell corrections
Situations Requiring Technical Decisions
Timing of Abstraction
Extract patterns after writing concrete implementation 3 times
Be conscious of YAGNI, implement only currently needed features
Prioritize current simplicity over future extensibility
Performance vs Readability
Prioritize readability unless profiling identifies a measurable bottleneck (e.g., response time exceeding SLA, memory exceeding allocation)
Measure before optimizing
Document reason with comments when optimizing
Granularity of Contracts and Interfaces
Overly detailed contracts reduce maintainability
Design interfaces where each method maps to a single domain operation and parameter types use domain vocabulary
Use abstraction mechanisms to reduce duplication
Scope Expansion
Apply implementation/edit instructions to the user's or task's specified scope. Escalate before expanding it.
Treat explicit quantities and targets ("one", "this file", "only X") as boundaries
Copy/move/mirror requests preserve content verbatim; edit content only when requested
Port/translation requests preserve intent and behavior; adapt only what the destination context requires
Before changing related files, symmetric locations, adjacent behavior, or adding helpful extras, escalate with the proposed expansion
Implementation Completeness Assurance
Impact Analysis: Risk-Scaled 3-Stage Process
Complete these stages sequentially before implementation. For an isolated change with no public contract, data-flow, integration, or configuration impact, concise notes or search evidence are sufficient. Use the structured report for cross-boundary, high-risk, or multi-consumer changes.
2. Understanding - Analyze each discovered location:
Role and purpose in the system
Dependency direction (consumer or provider)
Data flow (origin → transformations → destination)
Coupling strength
3. Identification - Record the affected units, risks, and implementation order at the depth required by the change. For expanded analysis, use:
## Impact Analysis
### Direct Impact
- [Unit]: [Reason and modification needed]
### Indirect Impact
- [System]: [Integration path → reason]
### Data Flow
[Source] → [Transformation] → [Consumer]
### Risk Assessment
- High: [Complex dependencies, fragile areas]
- Medium: [Moderate coupling, test gaps]
- Low: [Isolated, well-tested areas]
### Implementation Order
1. [Start with lowest risk or deepest dependency]
2. [...]
Proceed when discovery and understanding cover the files and behaviors named by the user or current task/design artifact, and the identified risks have an implementation or escalation path.
Unused Code Deletion
When an artifact made obsolete by the requested change is detected:
Delete it in the same change when its callers and generated/operational uses are checked
Preserve and report it when obsolescence is uncertain or deletion would expand beyond the files and behaviors named by the user or current task/design artifact
Do not implement unrelated dormant code merely because it was discovered
Existing Code Modification
Required by the requested change? No → Preserve unless the change proves it obsolete
Yes → Working and compatible? Yes → Fix/Extend
No → Repair or replace with migration/rollback evidence
Principle: Prefer clean implementation over patching broken code
How to use it
Copy the folder
Take shinpr/ai-development-guide from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
Check the name does not clash
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.