---
type: skill
domain: architecture
links: [Corpus_Callosum/CONSTITUTION.md, PULSE_OS.md]
---

# ABSTRACTION_ALCHEMIST
> **ROLE:** REUSABILITY EXPERT
> **TRIGGER:** "MODULARIZE"

## Core Mandate
Turn specific code into universal tools. But never abstract too early -- wait for the pattern to prove itself.

## Step-by-Step Protocol
1. **Brain check**: `python Autonomic_System/Utilities/Tools/brain_query.py --query "abstraction patterns for <domain>"`
2. **Apply the Rule of Three**: Only extract a shared abstraction when the SAME pattern appears in 3+ places. Two is a coincidence; three is a pattern.
3. **Design the interface first**: Write the function signature and docstring before the implementation. The API should be "easy to use correctly, hard to use incorrectly."
4. **Minimize public surface**: Export only what consumers need. Prefix internal helpers with `_`. Fewer public methods = fewer breaking changes.
5. **Verify stability and save**: Ensure the abstraction lives in `Utilities/` or a shared module. Record the pattern via `pulse_save.py`.

## The Rule of Three
| Occurrences | Action |
|---|---|
| 1 | Write it inline. Do not abstract. |
| 2 | Note the duplication. Still do not abstract. |
| 3+ | Extract to shared function/module. Now you have evidence. |

## Interface Design Patterns
```python
# PATTERN 1: Config object instead of many parameters
# BAD: 7 positional args
def start_worker(provider, model, tier, timeout, retries, log_level, dry_run): ...

# GOOD: Config dataclass
@dataclass
class WorkerConfig:
    provider: str = "google"
    model: str = "gemini-2.5-flash"
    tier: str = "standard"
    timeout: int = 120
    max_retries: int = 5

def start_worker(config: WorkerConfig): ...

# PATTERN 2: Protocol/ABC for plugin architecture
from typing import Protocol

class AgentProvider(Protocol):
    def send(self, prompt: str) -> str: ...
    def supports_tools(self) -> bool: ...

# Any class with send() and supports_tools() satisfies this -- no inheritance needed.

# PATTERN 3: Builder for complex objects
class TaskBuilder:
    def __init__(self, title: str):
        self._task = {"title": title, "status": "open"}
    def tier(self, t: str) -> "TaskBuilder":
        self._task["tier"] = t
        return self
    def build(self) -> dict:
        return self._task
```

## Metrics & Thresholds
| Metric | Threshold |
|---|---|
| Public methods per module | <7 (Miller's Law) |
| Parameters per function | <5 (use config object if more) |
| Inheritance depth | <3 levels (prefer composition) |
| Duplicate code before abstracting | 3+ occurrences minimum |
| Module fan-out (imports) | <10 direct dependencies |

## Anti-Patterns
- **Premature abstraction**: Creating `BaseTask`, `AbstractTask`, `TaskInterface` when you have exactly 1 task type. Wait for three.
- **Leaky abstraction**: If callers need to know internal details to use your API, the abstraction is broken. Redesign the interface.
- **God module**: A `utils.py` with 50 unrelated functions is not abstraction -- it is a junk drawer. Split by domain.

## Tools to Use
- `brain_query.py --query "abstraction patterns for <domain>"` -- check prior designs
- `pulse_relay.py --tasks "Extract shared module:architecture:standard"` -- delegate extraction
- `pulse_save.py --learnings "extracted <pattern>"` -- record successful abstractions
- `Hippocampus/Patterns/auto_patterns.md` -- check for recurring patterns worth abstracting

## Verification Checklist
- [ ] No abstraction created for fewer than 3 occurrences (Rule of Three)
- [ ] Public API surface <7 methods per module
- [ ] No function takes more than 5 parameters (use config object)
- [ ] Inheritance depth <3 (prefer composition over inheritance)
- [ ] All internal helpers prefixed with `_`
- [ ] Shared abstractions live in `Utilities/` or clearly named shared modules
