ritebook 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ritebook-0.1.0/.agents/skills/add-hexagonal-feature/SKILL.md +150 -0
- ritebook-0.1.0/.agents/skills/add-observability/SKILL.md +139 -0
- ritebook-0.1.0/.agents/skills/api-and-interface-design/SKILL.md +272 -0
- ritebook-0.1.0/.agents/skills/author-agent-skill/SKILL.md +266 -0
- ritebook-0.1.0/.agents/skills/bootstrap-python-app/SKILL.md +143 -0
- ritebook-0.1.0/.agents/skills/bootstrap-python-app/assets/pre-commit-config.template.yaml +32 -0
- ritebook-0.1.0/.agents/skills/bootstrap-python-app/assets/pyproject.template.toml +44 -0
- ritebook-0.1.0/.agents/skills/browser-runtime-verification/SKILL.md +214 -0
- ritebook-0.1.0/.agents/skills/ci-cd-and-automation/SKILL.md +234 -0
- ritebook-0.1.0/.agents/skills/code-review-and-quality/SKILL.md +308 -0
- ritebook-0.1.0/.agents/skills/code-review-and-quality/references/performance-checklist.md +23 -0
- ritebook-0.1.0/.agents/skills/code-review-and-quality/references/security-checklist.md +20 -0
- ritebook-0.1.0/.agents/skills/code-simplification/SKILL.md +221 -0
- ritebook-0.1.0/.agents/skills/context-engineering/SKILL.md +203 -0
- ritebook-0.1.0/.agents/skills/conventional-commits/SKILL.md +232 -0
- ritebook-0.1.0/.agents/skills/debugging-and-error-recovery/SKILL.md +205 -0
- ritebook-0.1.0/.agents/skills/deprecation-and-migration/SKILL.md +185 -0
- ritebook-0.1.0/.agents/skills/documentation-and-adrs/SKILL.md +169 -0
- ritebook-0.1.0/.agents/skills/doubt-driven-development/SKILL.md +164 -0
- ritebook-0.1.0/.agents/skills/doubt-driven-development/references/orchestration-patterns.md +28 -0
- ritebook-0.1.0/.agents/skills/format-python-code/SKILL.md +35 -0
- ritebook-0.1.0/.agents/skills/frontend-ui-engineering/SKILL.md +189 -0
- ritebook-0.1.0/.agents/skills/frontend-ui-engineering/references/accessibility-checklist.md +30 -0
- ritebook-0.1.0/.agents/skills/git-workflow-and-versioning/SKILL.md +195 -0
- ritebook-0.1.0/.agents/skills/idea-refine/SKILL.md +203 -0
- ritebook-0.1.0/.agents/skills/idea-refine/references/examples.md +181 -0
- ritebook-0.1.0/.agents/skills/idea-refine/references/frameworks.md +107 -0
- ritebook-0.1.0/.agents/skills/idea-refine/references/refinement-criteria.md +116 -0
- ritebook-0.1.0/.agents/skills/idea-refine/scripts/idea-refine.sh +12 -0
- ritebook-0.1.0/.agents/skills/incremental-implementation/SKILL.md +247 -0
- ritebook-0.1.0/.agents/skills/interview-me/SKILL.md +315 -0
- ritebook-0.1.0/.agents/skills/lint-python-code/SKILL.md +47 -0
- ritebook-0.1.0/.agents/skills/local-using-agent-skills/SKILL.md +87 -0
- ritebook-0.1.0/.agents/skills/performance-optimization/SKILL.md +336 -0
- ritebook-0.1.0/.agents/skills/performance-optimization/references/performance-checklist.md +38 -0
- ritebook-0.1.0/.agents/skills/planning-and-task-breakdown/SKILL.md +272 -0
- ritebook-0.1.0/.agents/skills/python-add-adapter/SKILL.md +156 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/SKILL.md +259 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/app_settings.template.py +14 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/configuration.template.md +21 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/env.example.template +7 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/env_settings_adapter_adapter.template.py +18 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/env_settings_adapter_init.template.py +7 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/env_settings_adapter_settings.template.py +67 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/exceptions.template.py +6 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/readme_configuration_section.template.md +8 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/test_app_settings.template.py +9 -0
- ritebook-0.1.0/.agents/skills/python-add-env-settings-adapter/assets/test_env_settings.template.py +120 -0
- ritebook-0.1.0/.agents/skills/python-add-port/SKILL.md +177 -0
- ritebook-0.1.0/.agents/skills/review-implementation-plan/SKILL.md +157 -0
- ritebook-0.1.0/.agents/skills/run-local-quality-gate/SKILL.md +37 -0
- ritebook-0.1.0/.agents/skills/run-python-tests/SKILL.md +40 -0
- ritebook-0.1.0/.agents/skills/security-and-hardening/SKILL.md +271 -0
- ritebook-0.1.0/.agents/skills/security-and-hardening/references/security-checklist.md +38 -0
- ritebook-0.1.0/.agents/skills/shipping-and-launch/SKILL.md +301 -0
- ritebook-0.1.0/.agents/skills/shipping-and-launch/references/accessibility-checklist.md +19 -0
- ritebook-0.1.0/.agents/skills/shipping-and-launch/references/performance-checklist.md +18 -0
- ritebook-0.1.0/.agents/skills/shipping-and-launch/references/security-checklist.md +18 -0
- ritebook-0.1.0/.agents/skills/source-driven-development/SKILL.md +190 -0
- ritebook-0.1.0/.agents/skills/spec-driven-development/SKILL.md +248 -0
- ritebook-0.1.0/.agents/skills/split-python-module/SKILL.md +110 -0
- ritebook-0.1.0/.agents/skills/test-driven-development/SKILL.md +236 -0
- ritebook-0.1.0/.agents/skills/test-driven-development/references/testing-patterns.md +41 -0
- ritebook-0.1.0/.agents/skills/update-project-docs/SKILL.md +136 -0
- ritebook-0.1.0/.agents/skills/using-agent-skills/SKILL.md +301 -0
- ritebook-0.1.0/.agents/skills/write-adr/SKILL.md +160 -0
- ritebook-0.1.0/.agents/skills/write-pytest-tests/SKILL.md +214 -0
- ritebook-0.1.0/.agents/skills/write-python-docstrings/SKILL.md +103 -0
- ritebook-0.1.0/.clinerules/000-readme.md +182 -0
- ritebook-0.1.0/.clinerules/001-cline-operating-guidance.md +33 -0
- ritebook-0.1.0/.clinerules/002-core-standards.md +65 -0
- ritebook-0.1.0/.clinerules/003-architecture-guardrails.md +133 -0
- ritebook-0.1.0/.clinerules/004-testing-standards.md +59 -0
- ritebook-0.1.0/.clinerules/005-docs-and-adr.md +40 -0
- ritebook-0.1.0/.clinerules/006-module-structure.md +85 -0
- ritebook-0.1.0/.clinerules/007-performance-and-observability.md +39 -0
- ritebook-0.1.0/.clinerules/008-configuration-and-secrets.md +55 -0
- ritebook-0.1.0/.clinerules/009-repo-navigation.md +78 -0
- ritebook-0.1.0/.clinerules/010-pr-and-commit-hygiene.md +31 -0
- ritebook-0.1.0/.clinerules/011-tooling-and-ci.md +51 -0
- ritebook-0.1.0/.clinerules/012-documentation-standards.md +56 -0
- ritebook-0.1.0/.clinerules/013-logging-conventions.md +51 -0
- ritebook-0.1.0/.clinerules/999-command-execution-safety.md +82 -0
- ritebook-0.1.0/.clinerules/workflows/improve.md +74 -0
- ritebook-0.1.0/.clinerules/workflows/update-repo-navigation.md +79 -0
- ritebook-0.1.0/.github/workflows/ci-cd.yaml +77 -0
- ritebook-0.1.0/.gitignore +12 -0
- ritebook-0.1.0/LICENSE +21 -0
- ritebook-0.1.0/PKG-INFO +74 -0
- ritebook-0.1.0/README.md +54 -0
- ritebook-0.1.0/pyproject.toml +66 -0
- ritebook-0.1.0/src/ritebook/__init__.py +5 -0
- ritebook-0.1.0/tests/__init__.py +1 -0
- ritebook-0.1.0/tests/unit/__init__.py +1 -0
- ritebook-0.1.0/tests/unit/test_package_metadata.py +5 -0
- ritebook-0.1.0/uv.lock +268 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-hexagonal-feature
|
|
3
|
+
description: Implement a new vertical feature slice or use case in a Python hexagonal project, including domain modeling, ports, application service, adapters when needed, and tests.
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0.0"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Add a Hexagonal Vertical Feature Slice
|
|
9
|
+
|
|
10
|
+
Use this skill to implement a new feature, use case, or business capability as a
|
|
11
|
+
vertical slice in a Python hexagonal project.
|
|
12
|
+
|
|
13
|
+
This skill focuses on a complete slice through domain, application, ports,
|
|
14
|
+
adapters when needed, and tests. When the change requires detailed port or
|
|
15
|
+
adapter work, use the specialized skill for that procedure instead of duplicating
|
|
16
|
+
it here.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- The project already has the standard hexagonal vertical-slice `src/` layout.
|
|
21
|
+
- The feature is clear enough that you understand its inputs, outputs, and core
|
|
22
|
+
business rules.
|
|
23
|
+
- The relevant inbound port already exists, or creating it is part of the same
|
|
24
|
+
change through `python-add-port`.
|
|
25
|
+
|
|
26
|
+
## Steps
|
|
27
|
+
|
|
28
|
+
### 1. Name the slice and use case
|
|
29
|
+
|
|
30
|
+
Choose a clear verb-noun name for the use case, for example `PlaceOrder`,
|
|
31
|
+
`RegisterUser`, or `SendNotification`. Use that name consistently for the
|
|
32
|
+
related files and classes.
|
|
33
|
+
|
|
34
|
+
Choose a `snake_case` slice name for the business capability, for example
|
|
35
|
+
`orders`, `user_registration`, or `notifications`. Use this as the package under
|
|
36
|
+
`src/<app_name>/features/<feature_name>/`.
|
|
37
|
+
|
|
38
|
+
### 2. Model the domain if needed
|
|
39
|
+
|
|
40
|
+
Create or update files under
|
|
41
|
+
`src/<app_name>/features/<feature_name>/domain/`:
|
|
42
|
+
|
|
43
|
+
- **Entity** — an object with identity that changes over time.
|
|
44
|
+
- **Value object** — an immutable descriptor (e.g. `EmailAddress`, `Money`).
|
|
45
|
+
- **Domain event** — something that happened (e.g. `OrderPlaced`).
|
|
46
|
+
|
|
47
|
+
Rules:
|
|
48
|
+
|
|
49
|
+
- Domain objects must be pure Python with no framework imports or I/O.
|
|
50
|
+
- Use `@dataclass(frozen=True)` for value objects.
|
|
51
|
+
- Raise domain-specific exceptions, not HTTP or database errors.
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
# src/<app_name>/features/<feature_name>/domain/<entity>.py
|
|
55
|
+
from dataclasses import dataclass
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class <Entity>:
|
|
59
|
+
id: str
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3. Define or confirm the required ports
|
|
63
|
+
|
|
64
|
+
Identify the application boundaries the feature needs:
|
|
65
|
+
|
|
66
|
+
- an inbound port when an external caller invokes a new use case
|
|
67
|
+
- one or more outbound ports when the application needs infrastructure
|
|
68
|
+
dependencies such as repositories, publishers, or gateways
|
|
69
|
+
|
|
70
|
+
If a required port does not exist yet, use `python-add-port` for the detailed
|
|
71
|
+
procedure. In this skill, keep the focus on deciding which boundaries the
|
|
72
|
+
feature needs. Inbound adapters should depend on inbound port contracts;
|
|
73
|
+
application services should satisfy those contracts and depend on outbound port
|
|
74
|
+
contracts for infrastructure.
|
|
75
|
+
|
|
76
|
+
If the use case needs command, query, or result objects, create or update them
|
|
77
|
+
under `src/<app_name>/features/<feature_name>/application/dtos/`.
|
|
78
|
+
|
|
79
|
+
### 4. Implement the application service
|
|
80
|
+
|
|
81
|
+
Create the use case implementation under
|
|
82
|
+
`src/<app_name>/features/<feature_name>/application/use_cases/`:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
class <UseCaseName>:
|
|
86
|
+
def __init__(self, repository: <EntityRepositoryPort>) -> None:
|
|
87
|
+
self._repository = repository
|
|
88
|
+
|
|
89
|
+
def execute(self, command: <Command>) -> <Result>:
|
|
90
|
+
...
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Rules:
|
|
94
|
+
|
|
95
|
+
- The application service depends only on domain objects and port interfaces.
|
|
96
|
+
- If an inbound port exists for the use case, the application service must satisfy
|
|
97
|
+
that contract.
|
|
98
|
+
- Keep command, query, and result DTOs under the owning slice's
|
|
99
|
+
`application/dtos/` and use them at the application boundary when dedicated
|
|
100
|
+
boundary types help clarify the use case.
|
|
101
|
+
- It must not import from `adapters/`.
|
|
102
|
+
- It must not perform I/O directly, including `open()`, HTTP calls, or database
|
|
103
|
+
access.
|
|
104
|
+
- If the feature needs a new adapter implementation for an existing or new
|
|
105
|
+
port, use `python-add-adapter` for that procedure.
|
|
106
|
+
|
|
107
|
+
### 5. Write unit tests
|
|
108
|
+
|
|
109
|
+
Create application-service tests under
|
|
110
|
+
`tests/unit/features/<feature_name>/application/`. If the change adds or changes
|
|
111
|
+
domain invariants, add or update domain tests under
|
|
112
|
+
`tests/unit/features/<feature_name>/domain/` as well.
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
class FakeRepository:
|
|
116
|
+
def __init__(self) -> None:
|
|
117
|
+
self.saved: list[object] = []
|
|
118
|
+
|
|
119
|
+
def save(self, entity: object) -> None:
|
|
120
|
+
self.saved.append(entity)
|
|
121
|
+
|
|
122
|
+
def test_<use_case_name>_happy_path() -> None:
|
|
123
|
+
repo = FakeRepository()
|
|
124
|
+
use_case = <UseCaseName>(repository=repo)
|
|
125
|
+
use_case.execute(<Command>(...))
|
|
126
|
+
assert len(repo.saved) == 1
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
TDD is encouraged when it fits the change. Writing tests before the
|
|
130
|
+
implementation is fine and often preferable.
|
|
131
|
+
|
|
132
|
+
- Prefer a hand-written fake for outbound ports. Use `MagicMock` only when a
|
|
133
|
+
narrow interaction assertion is clearer than asserting on fake state.
|
|
134
|
+
- Cover the happy path and at least one failure or edge case.
|
|
135
|
+
|
|
136
|
+
## Dependency direction reminder
|
|
137
|
+
|
|
138
|
+
Follow the target project's architecture guardrails when they are available. This
|
|
139
|
+
diagram is a quick dependency-direction reference only.
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
adapters/inbound → application → domain
|
|
143
|
+
adapters/outbound → (implements application/ports)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Never let an arrow point in the opposite direction.
|
|
147
|
+
|
|
148
|
+
Keep this diagram inside the owning feature slice. Cross-slice calls must go
|
|
149
|
+
through explicit inbound ports, published application APIs, or events rather than
|
|
150
|
+
private modules.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-observability
|
|
3
|
+
description: Add logs, metrics, traces, profiling, or operational notes for meaningful workflows without unsupported performance claims.
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.1.2"
|
|
6
|
+
dependencies:
|
|
7
|
+
tools: []
|
|
8
|
+
skills:
|
|
9
|
+
- debugging-and-error-recovery
|
|
10
|
+
- performance-optimization
|
|
11
|
+
- shipping-and-launch
|
|
12
|
+
- update-project-docs
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Add Observability
|
|
16
|
+
|
|
17
|
+
Use this skill when a workflow needs better runtime visibility, measurable
|
|
18
|
+
performance evidence, or operator-facing troubleshooting support.
|
|
19
|
+
|
|
20
|
+
## When to use this skill
|
|
21
|
+
|
|
22
|
+
Use this skill when you need to:
|
|
23
|
+
|
|
24
|
+
- profile an important path before or after a change
|
|
25
|
+
- add metrics or tracing around meaningful workflow boundaries
|
|
26
|
+
- improve logging context for operator-visible paths
|
|
27
|
+
- document dashboards, alerts, failures, or troubleshooting notes
|
|
28
|
+
- support investigation of latency, throughput, reliability, or resource usage
|
|
29
|
+
|
|
30
|
+
Do not use this skill to justify toy benchmarks, noisy logs, speculative
|
|
31
|
+
performance claims, or instrumentation that exposes sensitive data.
|
|
32
|
+
|
|
33
|
+
Use `performance-optimization` when the goal is to diagnose and fix a known or
|
|
34
|
+
suspected bottleneck. Use this skill when the goal is to add or improve the
|
|
35
|
+
signals that make runtime behavior observable. Use
|
|
36
|
+
`debugging-and-error-recovery` when an active failure needs reproduction,
|
|
37
|
+
localization, and root-cause repair. Use `shipping-and-launch` when observability
|
|
38
|
+
is part of a release checklist, rollout, or rollback plan.
|
|
39
|
+
|
|
40
|
+
## Steps
|
|
41
|
+
|
|
42
|
+
### 1. Define the workflow and signal
|
|
43
|
+
|
|
44
|
+
Identify the specific path, such as:
|
|
45
|
+
|
|
46
|
+
- a user-facing request or command
|
|
47
|
+
- an external service call chain
|
|
48
|
+
- persistence, parsing, rendering, or processing work
|
|
49
|
+
- a high-volume or latency-sensitive workflow
|
|
50
|
+
- a background job, queue, or scheduled task
|
|
51
|
+
|
|
52
|
+
State what you want to observe, for example latency, throughput, failure rate,
|
|
53
|
+
retry behavior, queue depth, memory growth, saturation, or error categories.
|
|
54
|
+
|
|
55
|
+
### 2. Measure before making claims
|
|
56
|
+
|
|
57
|
+
Before claiming an optimization or reliability improvement, capture a baseline
|
|
58
|
+
using representative inputs and environment notes.
|
|
59
|
+
|
|
60
|
+
Record:
|
|
61
|
+
|
|
62
|
+
- workload or dataset shape
|
|
63
|
+
- relevant environment assumptions
|
|
64
|
+
- before numbers
|
|
65
|
+
- what changed
|
|
66
|
+
- after numbers when applicable
|
|
67
|
+
- limitations of the measurement
|
|
68
|
+
|
|
69
|
+
If the outcome is better visibility rather than better performance, say that
|
|
70
|
+
plainly.
|
|
71
|
+
|
|
72
|
+
### 3. Instrument meaningful boundaries
|
|
73
|
+
|
|
74
|
+
Prefer instrumentation at boundaries where an operator or maintainer can act on
|
|
75
|
+
the signal, such as:
|
|
76
|
+
|
|
77
|
+
- workflow start and completion
|
|
78
|
+
- external I/O calls
|
|
79
|
+
- long-running processing steps
|
|
80
|
+
- retry loops and failure boundaries
|
|
81
|
+
- queue enqueue, dequeue, and completion points
|
|
82
|
+
|
|
83
|
+
Avoid scattering instrumentation across low-value internal helpers.
|
|
84
|
+
|
|
85
|
+
### 4. Add safe logs, metrics, or traces
|
|
86
|
+
|
|
87
|
+
Inspect existing observability conventions before adding new instrumentation.
|
|
88
|
+
Prefer established loggers, metric clients, tracing APIs, naming patterns, and
|
|
89
|
+
documentation locations. Do not introduce a new observability dependency or
|
|
90
|
+
vendor-specific tool unless the project already uses it or the user explicitly
|
|
91
|
+
asks for it.
|
|
92
|
+
|
|
93
|
+
Choose signals that fit the project conventions.
|
|
94
|
+
|
|
95
|
+
- Add logs for state transitions, decisions, and operator-visible failures.
|
|
96
|
+
- Add metrics for duration, volume, success, failure, and saturation where
|
|
97
|
+
supported.
|
|
98
|
+
- Add traces or spans around external I/O and cross-service boundaries where
|
|
99
|
+
supported.
|
|
100
|
+
- Propagate request, correlation, job, or tenant identifiers when available and
|
|
101
|
+
safe.
|
|
102
|
+
|
|
103
|
+
Do not log or emit secrets, credentials, personal data, or highly variable labels
|
|
104
|
+
that would create high cardinality.
|
|
105
|
+
|
|
106
|
+
### 5. Keep operational semantics clear
|
|
107
|
+
|
|
108
|
+
Use stable names and fields. Document what a signal means, when it increments or
|
|
109
|
+
records, and what action a maintainer should take when it changes.
|
|
110
|
+
|
|
111
|
+
When alerting or dashboards are affected, document thresholds, ownership, and
|
|
112
|
+
known limitations if those details are available.
|
|
113
|
+
|
|
114
|
+
### 6. Update documentation when needed
|
|
115
|
+
|
|
116
|
+
When the change matters operationally, update project-facing docs with:
|
|
117
|
+
|
|
118
|
+
- troubleshooting notes
|
|
119
|
+
- dashboard or alert references
|
|
120
|
+
- new failure modes
|
|
121
|
+
- rollout, migration, or on-call implications
|
|
122
|
+
- measurement caveats
|
|
123
|
+
|
|
124
|
+
Use `update-project-docs` for durable documentation updates.
|
|
125
|
+
|
|
126
|
+
### 7. Validate the signal
|
|
127
|
+
|
|
128
|
+
Exercise the instrumented workflow when practical and confirm the expected logs,
|
|
129
|
+
metrics, traces, or profile outputs are emitted. Check that labels and fields are
|
|
130
|
+
stable, low-cardinality, and free of sensitive data.
|
|
131
|
+
|
|
132
|
+
## Output checklist
|
|
133
|
+
|
|
134
|
+
- workflow and observed signal are explicit
|
|
135
|
+
- baseline and environment are captured when claims depend on numbers
|
|
136
|
+
- instrumentation is placed at meaningful boundaries
|
|
137
|
+
- logs, metrics, and traces use safe low-cardinality context
|
|
138
|
+
- operational documentation is updated when needed
|
|
139
|
+
- emitted signals were validated when practical
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-and-interface-design
|
|
3
|
+
description: Design stable APIs, module contracts, schemas, component boundaries, command interfaces, or other public integration surfaces that are predictable, documented, and hard to misuse.
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.1.3"
|
|
6
|
+
dependencies:
|
|
7
|
+
tools: []
|
|
8
|
+
skills: []
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# API and Interface Design
|
|
12
|
+
|
|
13
|
+
Use this skill when designing or changing a surface that another caller,
|
|
14
|
+
component, service, team, user, or automated process depends on. The goal is to
|
|
15
|
+
make the interface explicit, stable, observable enough to verify, and difficult
|
|
16
|
+
to misuse.
|
|
17
|
+
|
|
18
|
+
This applies to HTTP APIs, message contracts, library interfaces, module
|
|
19
|
+
boundaries, plugin hooks, command-line interfaces, component inputs, schemas,
|
|
20
|
+
configuration surfaces, and any other boundary where one part of a system talks
|
|
21
|
+
to another.
|
|
22
|
+
|
|
23
|
+
## When to use this skill
|
|
24
|
+
|
|
25
|
+
Use this skill when you need to:
|
|
26
|
+
|
|
27
|
+
- design a new public or cross-boundary interface
|
|
28
|
+
- change an existing interface without surprising consumers
|
|
29
|
+
- define input, output, error, or event contracts
|
|
30
|
+
- choose compatibility, versioning, pagination, or naming conventions
|
|
31
|
+
- review whether an interface is predictable and hard to misuse
|
|
32
|
+
|
|
33
|
+
Do not use this skill to standardize internal helper shapes that have no durable
|
|
34
|
+
consumer or observable boundary.
|
|
35
|
+
|
|
36
|
+
## Principles
|
|
37
|
+
|
|
38
|
+
### Hyrum's Law
|
|
39
|
+
|
|
40
|
+
With a sufficient number of users of an API, all observable behaviors of your
|
|
41
|
+
system will be depended on by somebody, regardless of what you promise in the
|
|
42
|
+
contract.
|
|
43
|
+
|
|
44
|
+
Treat observable behavior as a commitment. This includes response shape, error
|
|
45
|
+
codes, message text, ordering, timing, default values, side effects, and
|
|
46
|
+
undocumented quirks.
|
|
47
|
+
|
|
48
|
+
Design implications:
|
|
49
|
+
|
|
50
|
+
- expose only behavior you are willing to support
|
|
51
|
+
- avoid leaking implementation details through names, errors, timing, or data
|
|
52
|
+
shape
|
|
53
|
+
- plan deprecation before consumers depend on the old behavior
|
|
54
|
+
- remember that tests cannot prove a change is safe for undocumented consumer
|
|
55
|
+
dependencies
|
|
56
|
+
|
|
57
|
+
### One-version rule
|
|
58
|
+
|
|
59
|
+
Avoid forcing consumers to choose between multiple active versions of the same
|
|
60
|
+
interface or dependency. Multiple versions increase maintenance cost and create
|
|
61
|
+
compatibility problems when different consumers need different versions at the
|
|
62
|
+
same time.
|
|
63
|
+
|
|
64
|
+
Prefer extending one stable interface over forking it. If multiple versions are
|
|
65
|
+
unavoidable, document the support window, migration path, and removal criteria.
|
|
66
|
+
|
|
67
|
+
## Steps
|
|
68
|
+
|
|
69
|
+
### 1. Identify the boundary and consumers
|
|
70
|
+
|
|
71
|
+
State what boundary is being designed and who or what consumes it.
|
|
72
|
+
|
|
73
|
+
Capture:
|
|
74
|
+
|
|
75
|
+
- consumer types, such as users, services, modules, plugins, clients, scripts, or
|
|
76
|
+
operators
|
|
77
|
+
- whether the interface is public, internal but cross-team, or private to one
|
|
78
|
+
implementation
|
|
79
|
+
- expected stability and compatibility requirements
|
|
80
|
+
- inputs, outputs, side effects, errors, and ordering guarantees
|
|
81
|
+
- operational constraints such as latency, rate limits, retries, or idempotency
|
|
82
|
+
|
|
83
|
+
The more durable or widely consumed the interface is, the more explicit the
|
|
84
|
+
contract should be.
|
|
85
|
+
|
|
86
|
+
### 2. Define the contract before implementation
|
|
87
|
+
|
|
88
|
+
Describe the interface before building the implementation. Use the contract
|
|
89
|
+
format that fits the project, such as an OpenAPI document, schema file,
|
|
90
|
+
protocol definition, type definition, command help text, ADR, README section, or
|
|
91
|
+
test fixture.
|
|
92
|
+
|
|
93
|
+
At minimum, define:
|
|
94
|
+
|
|
95
|
+
- operation names and responsibilities
|
|
96
|
+
- required and optional inputs
|
|
97
|
+
- output shape and generated fields
|
|
98
|
+
- default values and side effects
|
|
99
|
+
- error shape and retry semantics
|
|
100
|
+
- compatibility expectations
|
|
101
|
+
- examples for common and edge cases
|
|
102
|
+
|
|
103
|
+
For example, a neutral resource contract might state:
|
|
104
|
+
|
|
105
|
+
```md
|
|
106
|
+
Operation: create item
|
|
107
|
+
Input: required name, optional description
|
|
108
|
+
Output: item identifier, name, description, creation timestamp
|
|
109
|
+
Errors: validation failed, duplicate name, unauthorized
|
|
110
|
+
Compatibility: future optional fields may be added to output
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 3. Choose consistent error semantics
|
|
114
|
+
|
|
115
|
+
Pick one error strategy for the boundary and apply it consistently.
|
|
116
|
+
|
|
117
|
+
Define:
|
|
118
|
+
|
|
119
|
+
- how callers detect success or failure
|
|
120
|
+
- whether errors are returned, raised, emitted, logged, or encoded as status
|
|
121
|
+
values
|
|
122
|
+
- machine-readable error identifiers
|
|
123
|
+
- human-readable messages
|
|
124
|
+
- which details are safe to expose
|
|
125
|
+
- whether an operation can be retried
|
|
126
|
+
|
|
127
|
+
For request-response APIs, this might be a status code plus a structured error
|
|
128
|
+
body. For libraries, it might be typed exceptions or result values. For command
|
|
129
|
+
interfaces, it might be exit codes plus structured output.
|
|
130
|
+
|
|
131
|
+
Do not mix patterns at the same boundary without a documented reason. If some
|
|
132
|
+
operations return empty values, some raise errors, and others return structured
|
|
133
|
+
errors, consumers cannot reliably predict behavior.
|
|
134
|
+
|
|
135
|
+
### 4. Validate at trust boundaries
|
|
136
|
+
|
|
137
|
+
Validate external or less-trusted data where it enters the system. After
|
|
138
|
+
validation, keep internal code focused on domain behavior instead of repeatedly
|
|
139
|
+
revalidating the same already-trusted data.
|
|
140
|
+
|
|
141
|
+
Validate data from:
|
|
142
|
+
|
|
143
|
+
- user input
|
|
144
|
+
- network requests
|
|
145
|
+
- files and configuration
|
|
146
|
+
- environment variables
|
|
147
|
+
- message queues or events
|
|
148
|
+
- third-party service responses
|
|
149
|
+
- generated or model-produced content
|
|
150
|
+
|
|
151
|
+
Treat third-party responses as untrusted. Validate their shape and content before
|
|
152
|
+
using them in logic, rendering, persistence, or security decisions.
|
|
153
|
+
|
|
154
|
+
Avoid scattering duplicate validation between internal functions that share the
|
|
155
|
+
same trusted contract.
|
|
156
|
+
|
|
157
|
+
### 5. Prefer additive compatible changes
|
|
158
|
+
|
|
159
|
+
Extend interfaces without breaking existing consumers.
|
|
160
|
+
|
|
161
|
+
Usually compatible:
|
|
162
|
+
|
|
163
|
+
- adding optional input fields
|
|
164
|
+
- adding output fields consumers can ignore
|
|
165
|
+
- adding new operations without changing existing ones
|
|
166
|
+
- adding new enum or status values only when consumers are expected to handle
|
|
167
|
+
unknown values
|
|
168
|
+
- relaxing overly strict validation when it does not create ambiguity
|
|
169
|
+
|
|
170
|
+
Usually breaking:
|
|
171
|
+
|
|
172
|
+
- removing fields, operations, status values, or error codes
|
|
173
|
+
- changing field meaning, type, units, default values, or ordering
|
|
174
|
+
- making optional fields required
|
|
175
|
+
- narrowing accepted input values
|
|
176
|
+
- changing idempotency, side effects, or authorization semantics
|
|
177
|
+
|
|
178
|
+
When a breaking change is unavoidable, use a deprecation and migration workflow
|
|
179
|
+
to plan communication, migration, compatibility support, and removal timing. If
|
|
180
|
+
the `deprecation-and-migration` skill is available, use it for that follow-up
|
|
181
|
+
planning.
|
|
182
|
+
|
|
183
|
+
### 6. Make naming predictable
|
|
184
|
+
|
|
185
|
+
Use names that match the existing interface style and domain language. Prefer
|
|
186
|
+
one convention per boundary over mixing styles.
|
|
187
|
+
|
|
188
|
+
Check names for:
|
|
189
|
+
|
|
190
|
+
- resource or concept names that reflect the domain rather than implementation
|
|
191
|
+
details
|
|
192
|
+
- operation names that describe intent without duplicating transport mechanics
|
|
193
|
+
- field names that use consistent casing, tense, and units
|
|
194
|
+
- boolean names that read clearly as true or false
|
|
195
|
+
- status values that are stable, documented, and safe for unknown-value handling
|
|
196
|
+
- identifiers that are hard to confuse across entity types
|
|
197
|
+
|
|
198
|
+
Do not import a naming convention from another language, framework, or transport
|
|
199
|
+
unless it is already the project convention or required by consumers.
|
|
200
|
+
|
|
201
|
+
### 7. Design collections and partial updates explicitly
|
|
202
|
+
|
|
203
|
+
For list or search operations, define:
|
|
204
|
+
|
|
205
|
+
- pagination or streaming behavior
|
|
206
|
+
- filtering and sorting options
|
|
207
|
+
- default limits and maximum limits
|
|
208
|
+
- result ordering stability
|
|
209
|
+
- empty result behavior
|
|
210
|
+
- consistency expectations when data changes during iteration
|
|
211
|
+
|
|
212
|
+
For partial updates, define:
|
|
213
|
+
|
|
214
|
+
- how omitted fields differ from explicit empty or null values
|
|
215
|
+
- whether updates are idempotent
|
|
216
|
+
- how conflicts are detected
|
|
217
|
+
- whether generated fields can be changed by consumers
|
|
218
|
+
|
|
219
|
+
### 8. Separate caller input from system output
|
|
220
|
+
|
|
221
|
+
Do not require callers to provide fields that the system owns, such as generated
|
|
222
|
+
identifiers, creation timestamps, computed values, or audit fields.
|
|
223
|
+
|
|
224
|
+
Keep separate shapes for:
|
|
225
|
+
|
|
226
|
+
- creation input
|
|
227
|
+
- update input
|
|
228
|
+
- persisted or returned output
|
|
229
|
+
- internal representation when it differs from the public contract
|
|
230
|
+
|
|
231
|
+
This separation keeps callers from depending on implementation details and makes
|
|
232
|
+
future changes easier.
|
|
233
|
+
|
|
234
|
+
### 9. Verify the interface from the consumer perspective
|
|
235
|
+
|
|
236
|
+
Validate the design and implementation with consumer-facing checks.
|
|
237
|
+
|
|
238
|
+
Useful verification includes:
|
|
239
|
+
|
|
240
|
+
- contract tests or schema validation
|
|
241
|
+
- examples that can be executed or copied safely
|
|
242
|
+
- compatibility tests for old and new consumers
|
|
243
|
+
- negative tests for validation and error behavior
|
|
244
|
+
- documentation review against actual behavior
|
|
245
|
+
- migration tests when changing an existing interface
|
|
246
|
+
|
|
247
|
+
Verification should prove the contract is understandable and stable from the
|
|
248
|
+
consumer's point of view, not only that the provider implementation works.
|
|
249
|
+
|
|
250
|
+
## Red flags
|
|
251
|
+
|
|
252
|
+
- observable behavior is undocumented but likely to be consumed
|
|
253
|
+
- operations at the same boundary use inconsistent error shapes
|
|
254
|
+
- input validation is missing at external boundaries
|
|
255
|
+
- third-party responses are trusted without validation or sanitization
|
|
256
|
+
- fields expose storage, framework, or implementation details unnecessarily
|
|
257
|
+
- collection operations have no pagination, streaming, or limit strategy
|
|
258
|
+
- partial updates do not define omitted, empty, and null value behavior
|
|
259
|
+
- compatibility impact is unclear for changed fields or status values
|
|
260
|
+
- examples require a specific framework even though the skill is meant to be
|
|
261
|
+
reusable
|
|
262
|
+
|
|
263
|
+
## Output checklist
|
|
264
|
+
|
|
265
|
+
- boundary and consumers are explicit
|
|
266
|
+
- contract is documented before or alongside implementation
|
|
267
|
+
- input, output, error, and side-effect semantics are consistent
|
|
268
|
+
- validation happens at trust boundaries
|
|
269
|
+
- changes are additive or have a migration plan
|
|
270
|
+
- naming follows the local interface convention
|
|
271
|
+
- collection and partial-update behavior is defined when relevant
|
|
272
|
+
- consumer-facing tests, examples, or documentation verify the contract
|