Extract shared behavior into deferred class abstractions following ISE EiffelBase patterns. Each abstraction level adds contracts, not implementation. Use with /eiffel.abstract command.
Extract shared behavior into deferred class abstractions following ISE EiffelBase patterns. Each abstraction level adds contracts, not implementation. Use with /eiffel.abstract command.
allowed-tools
Read, Grep, Glob, Edit, Write, Bash, Task
/eiffel.abstract - Deferred Class Extraction
Purpose: Extract shared behavior from 2+ concrete classes into a deferred class abstraction following ISE EiffelBase patterns. Each abstraction level adds contracts, not implementation.
Usage
/eiffel.abstract <library-path>
Example:
/eiffel.abstract d:\prod\simple_sorter
If no path provided, ask user: "Which library? Provide the full path (e.g., d:\prod\simple_sorter)"
Deferred as Contract — Abstract classes define WHAT via contracts, not HOW. Postconditions are mandatory on deferred features.
One Deferred Feature = One Responsibility — Each deferred feature represents exactly one decision a descendant must make.
Template Method — Make ONE feature deferred, derive others from it. Reference: PART_COMPARABLE where generates , , .
<
<=
>
>=
Invariants Enforce Laws — Class invariants constrain all descendants uniformly.
Flat-and-Wide over Deep — Do not create chains >3 levels without user approval.
Workflow
Step 1: Identify Target
If design-scan.md exists: Read <library-path>/.eiffel-workflow/evidence/design-scan.md and present abstraction findings to user. Ask which finding to implement.
If no scan exists: Ask user:
Which classes share behavior that should be extracted?
Provide 2+ class names (e.g., BUBBLE_SORT, QUICK_SORT)
Step 2: Analyze Shared Features
Read all target classes. For each feature that appears in multiple classes, classify:
Identify shared invariant conditions across classes
Identify creation procedure patterns (same make signature?)
Step 3: Design the Deferred Class
Create a class skeleton with:
deferred class
DEFERRED_NAME [G -> CONSTRAINT] -- generic only if needed
feature -- Access
shared_query: RETURN_TYPE
-- Description from shared contract.
deferred
ensure
result_property: Result.some_property -- MANDATORY postcondition
end
feature -- Status report
is_valid: BOOLEAN
-- Description.
deferred
ensure
definition: Result = (some_condition) -- MANDATORY postcondition
end
feature -- Basic operations
shared_effective_operation
-- Shared implementation (same in all descendants).
require
valid_state: is_valid
do
-- Actual shared implementation code
ensure
state_changed: some_postcondition
end
-- Template Method pattern
derived_operation: BOOLEAN
-- Derived from `base_operation`.
do
Result := not base_operation -- effective, derived from deferred
ensure
definition: Result = not base_operation
end
base_operation: BOOLEAN
-- Override point for Template Method.
deferred
ensure
-- postcondition on the one deferred drives the others
end
invariant
shared_law: some_condition_all_descendants_must_satisfy
end
CRITICAL RULES:
Every deferred feature MUST have a postcondition. A deferred feature without a postcondition is a specification gap — flag it to the user.
Effective features in the ancestor must have IDENTICAL implementation across all source classes. If they differ even slightly, make it DEFERRED.
Prefer Template Method: make ONE feature deferred, derive others from it.
Step 4: Present Design for Approval
Show the user:
Proposed deferred class — full skeleton
Descendant changes — what each concrete class gains/loses:
Do NOT suggest next skills automatically. The extraction is done — let the user decide what's next. Only mention other skills if the user asks.
Context Management (RLM Pattern)
This skill focuses ONLY on: <library-path>
DO NOT:
Read files outside this library directory
Load entire ecosystem into context
Keep large file contents in working memory after analysis
DO:
Use Task tool with Explore agent for ISE EiffelBase pattern questions
Ask targeted questions: "How does PART_COMPARABLE implement Template Method?"
Release context after getting answers
Anti-Drift
NEVER move different implementations into the ancestor as effective. If descendants differ, make it DEFERRED with contracts.
ALWAYS define postconditions on deferred features. Flag specification gaps to the user.
Extraction must PRESERVE all existing tests. Zero regressions.
Do not create chains >3 levels without user approval.
Oracle Gate before writing Eiffel code. No exceptions.
Skill Version Lock: If you discover skill improvements during workflow, queue them in <library-path>/.eiffel-workflow/skill-improvements.md — do NOT modify skills mid-workflow