| name | adr-eligibility-gate |
| description | Use BEFORE drafting any ADR when a story enters DESIGN phase, or when reviewing an ADR set that feels inflated. Runs a baseline-vs-decision gate: for each candidate architectural choice, determines whether it ratifies a genuine open question (→ ADR-worthy) or re-declares project baseline / skill-enforced convention (→ not ADR-worthy). Prevents ADR over-production by filtering out non-decisions before any draft is written. Triggers: "should I write an ADR for X?", "how many ADRs does this story need?", "ADR-INFLATION detected", "disambiguate baseline from decision".
|
ADR Eligibility Gate
Overview
This skill operationalizes the "When NOT to write an ADR" section of the
architecture-decisions skill as a pre-draft gate. Load it when considering
whether a candidate architectural choice warrants an ADR, before writing any
ADR body.
Core question: Does this choice ratify a genuine open question with real
trade-offs, or does it re-declare project baseline / existing skill-enforced
convention?
When to activate:
- DESIGN phase begins for a story
- Architect considers documenting a choice
- Reviewer flags
ADR-INFLATION (multiple ADRs for a story where 0-1 expected)
- User asks "should I write an ADR for X?" or "how many ADRs does this need?"
The 5-Question Checklist
For each candidate choice, answer these questions in order. The FIRST YES
determines the verdict.
Q1: Is this choice already enforced by a project skill or automated architecture test?
Examples of baseline (NOT ADR-worthy):
- "Pure domain service with no IO" → ADR-002 hexagonal baseline enforces this
- "CQS at method level" (one handler per command/query) →
clean-architecture-* skill
- "Validation at the boundary, keep core pure" → hexagonal baseline + tactical DDD
- "Convention-based DI registration" → project skill baseline
- "Value Object + pure validator" → tactical DDD baseline
If YES → NOT ELIGIBLE — <cite skill or ADR that already enforces this>
Q2: Is this choice a "good practice" or "avoid X antipattern" framing?
Examples:
- "No hardcoded phase names" → good practice, not a decision
- "Don't duplicate validation logic" → DRY principle, not a decision
- "Avoid magic strings" → coding standard, not a decision
Good practices and antipattern avoidance are baseline expectations, not
architectural decisions.
If YES → NOT ELIGIBLE — baseline good practice / antipattern avoidance
Exception: If the choice is framed as a context-mapping relationship
(e.g., "config as Published Language, guard as Conformist") rather than just
"no hardcoding", proceed to Q3.
Q3: Does the choice add complexity beyond the project baseline?
Load architecture-patterns skill. Check whether the choice is one of:
- Establishing or changing a layer boundary
- Choosing an aggregate boundary
- Adopting a pattern that adds complexity: CQRS+Bus, Event Sourcing, Saga,
Specification, ACL, Published Language, Conformist
- Establishing a bounded context boundary
- Affecting a cross-cutting concern (error handling strategy, validation approach)
If NO → NOT ELIGIBLE — no complexity addition beyond baseline
If YES → proceed to Q4.
Q4: Was the question actually raised by a story, AC, or measurable force in the current batch?
Silence = baseline default. ADRs (whether Accepted or Rejected) ratify
questions that were actually asked. A Rejected ADR is legitimate ONLY when
a story or measurable force in the batch raised the question.
Check:
- Does an AC explicitly require evaluating this choice?
- Did the event model surface this as a decision point?
- Did a technical constraint (performance, security, integration) force the question?
If NO → NOT ELIGIBLE — unraised question; non-decision artefact (G14)
If YES → proceed to Q5.
Q5: Does the choice have genuine trade-offs (not only upsides)?
Every ADR must demonstrate trade-off analysis. If the choice has only
benefits and no downsides, it is not a decision — it is a no-brainer that should
be baseline.
Check the 5 Universal Forces (from architecture-decisions skill):
- Simplicity
- Consistency
- Performance
- Evolvability
- Team capability
If the choice scores high on ALL five → NOT ELIGIBLE — no genuine trade-offs; should be baseline
If the choice creates tension between at least two forces → ELIGIBLE — genuine trade-off
Output Format
For each candidate:
Candidate: <short description>
Verdict: ELIGIBLE | NOT ELIGIBLE
Reason: <1-line citation to Q1-Q5 + skill/ADR section>
Example (US3 candidates):
Candidate: Pure domain service with no IO
Verdict: NOT ELIGIBLE
Reason: Q1 YES — ADR-002 hexagonal baseline enforces purity
Candidate: Fail-closed posture for dispatch gate
Verdict: ELIGIBLE
Reason: Q1 NO, Q2 NO, Q3 YES (cross-cutting error strategy), Q4 YES (AC-04), Q5 YES (over-blocking vs silent drift)
Candidate: VO + validation at boundary
Verdict: NOT ELIGIBLE
Reason: Q1 YES — hexagonal baseline + tactical DDD enforce this
Candidate: No hardcoded phase names
Verdict: NOT ELIGIBLE (as framed)
Reason: Q2 YES — "no hardcoding" is a good practice, not a decision
Candidate (reframed): Config as Published Language, guard as Conformist
Verdict: ELIGIBLE
Reason: Q2 NO (context-mapping), Q3 YES (Published Language adoption), Q4 YES (event model), Q5 YES (coupling vs drift)
Integration with architecture-decisions Skill
This gate does NOT replace architecture-decisions — it precedes it:
- Gate (this skill): Determines IF an ADR is warranted.
- Template (architecture-decisions): Provides HOW to write the ADR body if the gate passes.
Load order:
adr-eligibility-gate → verdict per candidate
- If
ELIGIBLE → load architecture-decisions for template + lifecycle
Anti-patterns Detected by This Gate
| Anti-pattern | Description | Gate catches it via |
|---|
| ADR-INFLATION | Multiple ADRs for baseline re-declarations | Q1 |
| NON-DECISION | ADR for a choice with no alternatives | Q5 |
| BASELINE DRIFT | Project baseline not reflected in ADR filters | Q1 + Q3 |
| UNRAISED QUESTION | ADR for a question nobody asked (G14) | Q4 |
| GOOD-PRACTICE ADR | ADR for "avoid X" or "always Y" framing | Q2 |
Real-World Calibration
Run this gate on existing ADRs to verify calibration:
| ADR | Expected Verdict | Actual Q-path |
|---|
| ADR-001 (Result type) | ELIGIBLE | Q1 NO, Q3 YES, Q4 YES (#47), Q5 YES |
| ADR-002 (Hexagonal) | ELIGIBLE | Q1 NO (first in project), Q3 YES, Q4 YES (#47), Q5 YES |
| ADR-003 (Config cascade) | ELIGIBLE | Q1 NO, Q3 YES, Q4 YES (#47), Q5 YES |
| ADR-004 (pure service, US3) | NOT ELIGIBLE | Q1 YES — ADR-002 baseline |
| ADR-005 (fail-closed, US3) | ELIGIBLE | Q1 NO, Q3 YES (cross-cutting), Q4 YES, Q5 YES |
| ADR-006 (VO + validation, US3) | NOT ELIGIBLE | Q1 YES — hexagonal + DDD baseline |
| ADR-007 (no hardcoding, US3) | NOT ELIGIBLE (as framed) / ELIGIBLE (reframed) | Q2 YES (good practice) / Q3 YES (Published Language) |
If the gate yields unexpected verdicts on ADR-001..003, recalibrate Q1/Q3.
Dependencies
plugins/skills/architecture-decisions/SKILL.md (cites "When NOT to write an ADR")
plugins/skills/architecture-patterns/SKILL.md (cites baseline patterns for Q3)
Evals
Content evals
-
Candidate: "pure domain service with no IO"
Expected: NOT ELIGIBLE — ADR-002 hexagonal baseline
-
Candidate: "fail-closed posture for a security gate"
Expected: ELIGIBLE — Q3 YES (cross-cutting concern), Q5 YES
-
Candidate: "no hardcoded phase names"
Expected: NOT ELIGIBLE — Q2 YES (good practice)
Trigger evals
Should-trigger (8):
- "should I write an ADR for this choice?"
- "how many ADRs does story X need?"
- "is this ADR-worthy?"
- "ADR-INFLATION detected in DESIGN review"
- "disambiguate baseline from decision"
- "this feels like too many ADRs"
- "evaluate candidate architectural choice"
- "before drafting ADR"
Should-not-trigger (8):
- "how do I write an ADR?" →
architecture-decisions
- "what's the ADR template?" →
architecture-decisions
- "list existing ADRs" → grep / index read
- "ratify ADR-005" → human gate
- "event modeling for story X" →
architecture-patterns
- "which DDD pattern should I use?" →
architecture-patterns
- "write the ADR body" →
architecture-decisions
- "supersede ADR-001" →
architecture-decisions lifecycle
Version
v1.0 — 2026-06-28 — Initial release (genesis output, US3 case study)