Defect Shift-Left

SkillDev tools

Places every error detection at the earliest stage of the pipeline that is technically capable of catching it. Use when designing or auditing a CI/CD pipeline, choosing tooling, deciding where a check belongs, or asking "could this have been caught earlier?"

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Defect Shift-Left skill

What this skill tells your AI

The instructions your AI receives, as published by l-gevity/l-gevity-skills in .agents/skills/defect-shift-left/SKILL.md and read by ahel’s review.

Pipeline stages have a strict order. Every defect has an earliest stage at which it can be caught. Catching it later is always a regression.

Core Directives

  1. Prevent over detect. Make invalid states unrepresentable before adding a check.
  2. Earliest possible stage is mandatory. If a check can run at stage N, running it at N+1 is a regression.
  3. Replace same-scope duplicates. When shifting a check earlier, remove any later check that covers the same scope. Keep a later backstop only when it covers a broader or less-bypassable scope.
  4. Fail loud at the origin. Errors must surface where they originated.

Improvement Trio

  • defect-shift-left: move defect detection earlier.
  • push-out: move recurring operational work outward.
  • bring-down: move bespoke code down into reusable capability.

1. The Ladder

StageRankPhaseWhat runs here
00LanguageType system, syntax, language semantics
11DesignSpec, ADR, threat model, schema
22AuthoringLSP, in-editor lint, formatter
33Pre-commitFormat, fast lint, secret scan, commit-msg hook
44CompileCompiler, type-checker, codegen
55Build / Static analysisFull lint, depcheck, SAST, license, CVE, bundle, IaC, fitness functions
66Unit testLocal test runner, property tests
77Integration / ContractCI suite, contract tests, container builds
8a8Pre-deploy staticMigration dry-run, config-vs-env, capacity, IAM diff (deploy abortable)
8b9Deploy executionSmoke, health probes, slot readiness (rollback on failure)
910Canary / StagingPartial traffic, real env, perf regression
1011Production runtimeLive traffic, monitoring
1112Post-incidentForensics, RCA

Cost grows roughly geometrically with rank. The ladder is monotonic — later detection is never neutral. Use Rank for distance math; stage labels like 8a and 8b are names, not numbers.

Stages 8a and 8b are split because some defects only become detectable when target-environment state is available; pre-deploy can abort cheaply, deploy execution requires rollback.


2. Stage 0 — Make Invalid States Unrepresentable

Before adding any check at Stage ≥1, ask: can a type or schema make this defect unrepresentable? If yes, the check belongs at Stage 0.

TechniqueEliminates
Strong / branded typesType confusion, semantic mixing
Sum types + exhaustive matchingMissing case, silent fallthrough
Option / Result typesNull deref, silent failure
Refinement typesRange, off-by-one
Linear / affine typesUse-after-free, double-close
Schema-as-codeConfig drift, contract mismatch
Const / immutable defaultAccidental mutation, race
Strict compiler flags (strict, noUncheckedIndexedAccess, strictNullChecks, --strict)Whole defect classes without writing new types — flip a flag, the compiler enumerates the gaps

3. Defect Taxonomy → Earliest Stage

Stage vs rank. The Stage column is the label from §1; for distance math use the rank. Labels 07 equal their rank, then 8a→8, 8b→9, 9→10, 10→11, 11→12 — never subtract stage labels.

Defect classStageMechanism (fallback)
Type mismatch, null deref, semantic-type mixing0Type system
Missing case handling0Exhaustive sum types
Off-by-one / range0Refinement types (else 6: property test)
Use-after-free, race0Linear / borrow types (else 5: static analysis)
Generated code drift from schema0Codegen types (else 5: codegen drift check)
Contract / schema absent or ambiguous1Shared schema / spec
Authorization model gap1Threat model (else 7: security test)
Style, formatting, unused code, API misuse2LSP / editor (else 5: lint)
Banned API / unsafe pattern2LSP rule (else 5: lint)
Forbidden architectural dependency2Editor import rule (else 5: depcheck / lint)
Aspect coverage gap — a governed subsystem lacks the aspect's mechanism5Fitness function over the subsystem registry (else 7: policy test)
Committed config violates schema2Editor schema hint (else 5: schema validation)
Secret in source3Pre-commit scanner (else 5: SAST)
Symbol resolution / missing import4Compiler
CVE in dependency5SCA audit
License incompatibility5License audit
Bundle / artifact regression5Bundle validator
Logic error in pure function6Unit test
Property violation across input space6Property test
Integration boundary mismatch7Contract test
Container / build reproducibility7CI image build
Performance regression (micro)7Benchmark (else 9: load test)
Migration vs current schema8aDry-run against prod DB
Irreversible migration8aReversibility check
Cross-service version skew8aVersion-matrix gate
Backwards-incompatible API change8aContract diff vs deployed
Missing / expired secret in target env8aSecret-store presence check
Undefined feature flag in target8aFlag-store consistency
Target-env config violates schema8aPre-deploy config / env validation
Capacity / quota exceeded8aResource projection
IAM permission expansion8aIAM diff
Cost / budget breach8aCost projection
Missing rollback artifact8aRegistry probe
Compliance approval missing8aPolicy gate
Artifact crashes on boot8bStartup smoke
Health probe never passes8bOrchestrator readiness gate
Target env unreachable dependency8bBoot connectivity check
Resource exhaustion under load9Load test
Real-world latency / SLO breach10Production monitoring

4. Audit Protocol

  1. Inventory every check and the stage it runs at, including manual reviews, advisory warnings, and runtime asserts.
  2. Classify each by defect class (§3).
  3. Look up the earliest possible stage and its rank (§1).
  4. Compute rank distance = current rank − earliest rank.
  5. Prioritize by rank distance × frequency × blast radius.
  6. Move the check to the earliest feasible stage.
  7. Gate it. A correct-stage check that does not block is still a detection gap.
  8. Remove later same-scope duplicates once the earlier gate is proven. Keep only broader or less-bypassable backstops.
  9. Audit every escaped defect: find its earliest possible stage and place a gate there.
SituationAction
Proposed = earliest possibleProceed
Proposed > earliest, earlier feasible nowReject — implement at the earlier stage
Proposed > earliest, earlier requires effortDocument gap as technical debt; schedule shift
No check; defects only found in productionCritical — work backward from Stage 10
Check requires target-env stateStage 8a is earliest — do not push to Stage 10
Check exists but does not blockPromote to blocking gate or remove as theatre
Later check covers same scope as earlier checkRemove later duplicate after proof
Later check covers broader / unbypassable scopeKeep as backstop; record distinct scope

Emit one coder-facing row per gap:

Defect classCurrent stage (rank)Earliest stage (rank)Rank distanceMechanismDecisionOwner/checkVerificationNext action

If a gap remains, state: "Detection Gap: defect class catchable at Stage [X] (rank [Xr]), currently at Stage [Y] (rank [Yr]). Mechanism: [...]."


5. Anti-Patterns

PatternActual / earliest
Runtime check for type errorsStage 10 / Stage 0
CI formatting check with no editor supportStage 5 / Stage 2
Linter only in CIStage 5 / Stage 2 + Stage 5
Code review as primary defect filterManual / Stage 2–5
Production monitor for known-bad inputStage 10 / Stage 0
Compile errors hidden behind dynamic typesStage 6+ / Stage 0
Manual deployment checklistManual / Stage 5 or 8a
Documentation as the contractStage 7+ / Stage 1
Deploy-and-pray monitoringStage 10 / Stage 8a
Migration applied without dry-runStage 8b–10 / Stage 8a
Secrets / config validated only at runtimeStage 10 / Stage 8a
Manual rollback on deploy failureStage 10 / Stage 8b
No canary, full traffic on new artifactStage 10 / Stage 9

These three do not detect late — they suppress a defect rather than move it earlier, so they have no "earliest stage":

  • Retry as error handling — masks a Stage 10 failure indefinitely instead of surfacing it.
  • Catch-and-log silent failure — swallows the error, violating "fail loud at the origin" (Directive 4).
  • Warnings nobody reads — detection with no gate; see §6.4.

6. Common Shift Patterns

Recurring moves that shift a defect class from a later stage to an earlier one; recognise them and apply them deliberately. Read references/shift-patterns.md for the recipe, tooling, and completion condition of each.

  • 6.1 Untyped → strict-typed source — type errors and null derefs from Stage 6+ to Stage 0; complete only when the strict typecheck blocks at pre-commit and in CI.
  • 6.2 ADR → executable architectural rule — prose rules become lint config at Stages 2 and 5; the encoding pattern is architecture-as-code.
  • 6.3 Hand-validated boundary → schema-as-code — one schema artifact fanned out to the codegen, editor, build, and pre-deploy rungs.
  • 6.4 Optional check → blocking gate — the most common shift-left failure is the right check at the right stage that does not block; a check nobody runs has zero shift-left value.
  • 6.5 Scope-justified backstops — a later duplicate stays only when it is broader or less bypassable than the earlier, faster layer (Directive 3).
  • 6.6 Hand-checked aspect coverage → fitness function — a coverage gap moves from review to Stage 5; the subsystem registry is the population and the test-strategy oracle is the assertion.

7. Stack-Aware Tooling Survey

Use this only when the user asks for tooling recommendations or implementation options; a plain shift-left audit stops at the missing category. Detect the stack, map each gap to a stage, defect class, and tool category, and name specific products only on request, each cited with a source and a currency signal. Read references/tooling-survey.md for the stage-to-category table and the output row. A tool that does not map to a rung on the ladder has no place in the output.

8. See also

  • architecture-as-code — the codified-architecture pattern this skill names in §6.2.
  • architecture-guidelines — first-principles rules whose violations this skill places on the ladder.
  • ci-cd-reliability-architecture — pipeline rules that staff Stages 5–10.
  • push-out — move recurring operational work out of human/manual execution into durable systems.
  • bring-down — move bespoke or duplicated code down into reusable capability.
  • continuous-improvement — how to promote a recurring escaped-defect into a permanent gate (Directive 1).

Signals

GitHub stars
43
Forks
9
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
defect-shift-left
Source
github.com/l-gevity/l-gevity-skills