Define or refactor subsystem interfaces into small, explicit contracts with clear ownership, narrow scope, stable semantics, and README-first documentation. Use when designing a new API, collapsing ad hoc module boundaries into a few coherent interfaces, hardening internal contracts, or rewriting subsystem docs so engineers can understand the system by reading README.md files, docstrings, and code only.
Design interfaces the way durable systems do:
The target is an interface that feels old in the best way:
Think Unix and Linux, not app-framework churn.
This skill is for interface hardening, not generic architecture prose.
Reduce a subsystem until a reader can answer these questions quickly:
If the answer requires reading five modules and guessing, the interface is not done.
If the behavior of the subsystem is mostly encoded in ad hoc helper functions and not in a small set of named interfaces, the design is not done.
Prefer this hierarchy:
README.mdDo not create a new top-level taxonomy document unless the user explicitly wants one.
The default move is to consolidate interface definitions into the correct subsystem README.md files.
The user should be able to understand the subsystem by reading:
README.mdand nothing else.
Use this skill when the user asks for things like:
Typical triggers:
Every interface must say:
If two interfaces claim authority over the same operation or field, pick one. The other is either:
Ambiguous authority is not a documentation problem. It is an interface bug.
Do not confuse:
with the interface itself.
Multiple transports can implement one interface. One transport can also expose multiple interfaces. Name the interface by responsibility, not by wire format.
Do not let implementation detail harden into architecture accidentally.
A good subsystem README.md should let a new engineer answer:
Do not dump global architecture into every README. Give each README one job.
The README is the manual for the subsystem. It should define the contract, boundaries, ownership, and compatibility story, not just list folders.
Aim for:
Avoid:
Prefer text that reads like a subsystem maintainer wrote it for the next maintainer, not like a platform team wrote it for a launch review.
Good interface names survive implementation changes:
Public Access APIHost Runtime APIGuest Runtime APIBad interface names mirror folder layout or current wiring accidents:
Good interface names should survive a rewrite of transports, frameworks, directories, and helper packages.
The right way to combine complexity is:
The wrong way is:
If the system currently composes through ad hoc functions, collapse those behaviors behind a smaller number of named interfaces.
Do not tolerate:
Every interface description should be executable as a mental model.
Find the real surfaces:
Write them down as concrete resources and operations, not abstractions yet.
Also inventory:
Partition surfaces into a small number of interfaces.
A good interface groups operations that:
Do not force “three” if four is cleaner. Do not keep seven if three is cleaner.
The number of interfaces is not the goal. Coherent cuts are the goal.
For every endpoint / service / CRD path, classify it as one of:
authoritativecompatibilitydebug-onlyoperationalDefinitions:
authoritative: the canonical contract for doing real workcompatibility: temporary old surface during migrationdebug-only: operator introspection, not product coreoperational: health, metrics, openapi, readiness, etc.If a surface does not fit one of those categories cleanly, the design is not settled yet.
For each resource or state subtree, define:
Prefer small tables.
Example:
| Area | Writer | Meaning |
| --- | --- | --- |
| `spec` | controlplane API | desired lifecycle and resource intent |
| `status.runtime` | host-agent | observed runtime facts from the compute host |
| `status.summary` | controlplane controller | public lifecycle projection |Default locations:
Also update local package docs and type comments so they agree with the README.
After the contract is written:
If code and docs disagree, code wins for current truth, then docs are corrected.
If the code reveals the interface is wrong, fix the interface, not just the prose.
Use this template.
# <Subsystem>
One sentence describing what this subsystem does.
## Scope
What this subsystem owns.
What it does not own.
## Interface boundary
- primary interface(s)
- neighboring systems
- authoritative contract
- compatibility/debug/operational split
## Ownership
Small tables for spec/status/runtime/projection ownership if applicable.
## Surface
Routes, services, resources, or protocol entry points.
## Semantics
What each major operation guarantees.
What it refuses.
What is synchronous, asynchronous, or eventually consistent.
## Compatibility and debug
What is transitional, what is debug-only, and what should eventually be deleted.
## References
Links to the neighboring subsystem README, proto, or type definitions.Optional sections when useful:
GlossaryConstraintsState modelVersioningNon-goalsTop-level module docs should say which interface the module implements.
Examples:
//! ConnectRPC service implementations for the host-agent.
//!
//! This module is the authoritative Host Runtime API: the controlplane-to-host
//! contract for lifecycle, health, migration, release, and artifact operations.// Workspace is the durable declarative envelope around the Host Runtime API.
// Spec carries controlplane intent; status combines controller-authored
// projection with host-agent-authored runtime fact.When refactoring an existing system:
The subsystem README must stand on its own. Do not make readers hop through a taxonomy doc to understand the boundary.
Do not define interfaces by current file organization.
Do not define “the WebSocket API” or “the protobuf API” unless transport is actually the product boundary.
If one README says controlplane owns preview status and another says host-agent owns it, the interface is broken.
Do not turn every README into a full system architecture essay. Put enough context to understand the boundary, then stop.
Do not create five tiny interfaces where one coherent subsystem contract would do.
Do not preserve ad hoc helper layers just because they already exist. If they encode part of the real contract, pull that behavior upward into the interface.
These former standalone skills are bundled here as references to keep the runtime list compact. Load only the reference that matches the user's exact product, framework, or failure mode.
| Former skill | Reference | Description |
|---|---|---|
dedalus-generate-interface | references/skills/dedalus-generate-interface/SKILL.md | Define or refactor subsystem interfaces into small, explicit contracts with clear ownership, narrow scope, stable semantics, and README-first documentation. Use when designing a new API, collapsing ad hoc module boundaries into a few coherent interfaces, hardening internal contracts, or rewriting subsystem docs so engineers can understand the system by reading README.md files, docstrings, and code only. |