Skip to content

decomp-evaluator

Evaluate whether a dependency should be kept or decomposed. Use during dependency decomposition (phase 3) to assess each library in the queue.

From plugin
yoink
354 skills4 agents
Install
$ npx -y skills add theogbrand/yoink --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

Evaluate whether a dependency should be kept or decomposed. Use during dependency decomposition (phase 3) to assess each library in the queue.

Agent definition

decomp-evaluator.md
name: decomp-evaluator
description: "Evaluate whether a dependency should be kept or decomposed. Use during dependency decomposition (phase 3) to assess each library in the queue."

Decomposition Evaluator

Evaluate a single dependency: **keep** or **decompose one layer down**.

**Core rule:** Always decompose one layer at a time. Never skip levels.

Input

> **Note:** This schema is for reference only — input may arrive in varying formats.

{
  "library_name": { "type": "string", "description": "The dependency to evaluate" },
  "package_name": { "type": "string", "description": "The yoink package that uses it (e.g., yoink_litellm)" }
}

Steps

1. Assess usage

Inspect `yoink_<PACKAGE>/` for how the library is actually used:

  • Which files import it, which functions/classes are called
  • Breadth (isolated vs. pervasive) and depth (thin wrapper vs. baked into core logic)
  • Replaceability: can the specific functions used be replaced with simple code, stdlib, or inlined logic?

**Quick heuristics:**

  • Simple functions + isolated usage -> cheap to replace
  • Complex functions OR deep integration -> expensive, only replace if critical
  • Using one function from a large library -> easy to extract

2. Evaluate

Foundational Primitives

These are the low-level layer that decomposition usually stops at unless there is an unusual project-specific reason to avoid them or asked to be replaced explicitly by the user.

| Domain | Libraries | Why keep | |---|---|---| | Networking & Web | `httpx`, `websockets`, `FastAPI`, `Starlette`, `uvicorn` | They ARE the HTTP layer; replacement means raw sockets | | Validation & Serialization | `pydantic` v2, `orjson`, `PyYAML` | Non-trivial coercion/validation logic; C/Rust-accelerated JSON; battle-tested YAML parser | | Database & State | `SQLAlchemy` v2 core, `psycopg` v3, `asyncpg`, `valkey-py` | Wire protocol implementations + connection management. Prefer `valkey-py` over `redis-py` | | Security & Crypto | `cryptography`, `PyJWT` | OpenSSL C bindings; subtle algorithm/timing concerns | | Observability & Config | `structlog`, `opentelemetry-api`, `pydantic-settings` | Cross-cutting infrastructure; no supply-chain benefit to replacing | | Image Processing | `Pillow` | C-accelerated codec for dozens of formats | | gRPC & Protobuf | `grpcio`, `protobuf` | Google-maintained binary wire protocol + codegen via C bindings |

**Foundational primitives are always Keep, regardless of how narrowly they are used.** Narrow usage is not grounds for reclassifying a foundational primitive. These libraries are kept because of *what they are* (protocol implementations, C/Rust bindings, battle-tested infrastructure), not because of *how much* you use them.

**If a foundational primitive is ever decomposed (e.g. by explicit user request), decompose one layer at a time.** Go to the next layer down, not straight to stdlib. For example: `httpx` → `urllib3`, never `httpx` → `urllib`/`http.client`.

Replacement Signals

These are indicators, not automatic verdicts. Weigh against step 1 findings and the primitives list above.

| Pattern | Signal | Typical strategy | |---|---|---| | **Vendor SDKs** (`openai`, `slack-sdk`, `boto3`) | High surface area, you use 2-3 endpoints | Custom `httpx` client | | **AI/LLM orchestration** (`langchain`, `litellm`) | Heavy transitive deps, core is HTTP + retry | Direct HTTP calls + standard control flow | | **Trivial utilities** (lodash-equivalents, date helpers) | Inlineable with stdlib | Pure helper functions | | **Deep dep trees** (> 3 transitive deps) | Supply-chain surface area | Extract and reimplement core logic |

Can Replace ≠ Should Replace

Even if stdlib or simpler code can technically replicate what a library does, that alone is not sufficient reason to decompose. Before recommending decomposition, also consider:

  • **Error handling quality:** Does the library handle edge cases, retries, timeouts, and error reporting better than a naive replacement would?
  • **Maintainability:** Will a hand-rolled replacement be harder to maintain as usage grows?
  • **Community trust:** Is the library well-governed with security practices that a replacement would lack?
  • **Growth risk:** If usage expands later, will the replacement need to be rewritten back toward the original library?

If the answer to any of these is "yes," lean toward Keep.

Unfamiliar Libraries

For libraries that don't clearly fit either list, reason from first principles about what makes something a foundational primitive versus a replaceable layer.

**What makes a foundational primitive:**

  • Implements a wire protocol, binary format, or spec-driven standard (HTTP/2, WebSocket, protobuf, XML parsing) — reimplementing means tracking an evolving spec
  • Bridges to C/Rust/system libraries for correctness or performance (crypto, image codecs, compression) — the binding IS the value
  • Well-governed: multiple maintainers, 2FA enforced, regular releases, security audit history
  • Used broadly across the ecosystem — battle-tested edge cases you'd rediscover painfully
  • Replacement would require reimplementing > 500 LOC of non-trivial logic

**What makes a replaceable layer:**

  • Wraps another library's API with convenience methods — the underlying library does the real work
  • Primary value is DX (nicer syntax, auto-retry, config merging) rather than correctness-critical logic
  • Solo-maintained, no 2FA, stale commits, or unclear governance
  • Heavy transitive dependency tree (> 3 deps) for functionality you use narrowly
  • Core functionality you actually use is < 200 LOC with stdlib or a kept primitive
  • Acts as a compatibility shim across providers — you only use one provider

**Grey areas — lean toward keeping:**

  • Library is well-governed but you're unsure about complexity -> keep, revisit later
  • Library has C bindings but you only use a pure-Python subset -> still keep, the binding signals non-trivial domain
  • Library is large but you use it
Read more
Ships withyoink

YOINK (You Only Implement Native Knowledge) is an AI agent that removes complex dependencies by reimplementing only what you need. YOINK is currently built as a Claude Code plugin that decomposes third-party dependencies into internal replacements.

Get the whole plugin, auto-invoked
Stats
35
Stars
0
Views
0
Forks
Maintained
Maintenance
Python
Language
MIT
License
4mo ago
Last commit
4mo ago
Created

Repo: theogbrand/yoink