DevRitesAPI接口
ViktorsBaikers2026-10-27查看 1509复制 1880
在实施之前制定稳定的 API、类型、模块或前端/后端合约。当切片跨越边界时使用;不适用于内部助手。
📘如何使用这个技能
- 1复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
- 2打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
- 3粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
- 4直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景
💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。
SKILL.md4550 chars
---
name: devrites-api-interface
description: Shape stable API, type, module, or frontend/backend contracts before implementation. Use when a slice crosses a boundary; not for internal helpers.
user-invocable: false
---
<!-- loads: {"always":["devrites-lib/reference/standards/core.md"],"triggers":{"afk":["devrites-lib/reference/standards/afk-hitl.md"],"deprecation":["devrites-lib/reference/standards/deprecation.md"],"security":["devrites-lib/reference/standards/security.md","rite-review/reference/security-review.md"]},"workspace":["spec.md","plan.md","tasks.md","state.md","decisions.md"],"rootOnly":["devrites-lib/reference/standards/afk-hitl.md"]} -->
> Read-set manifest: `devrites-engine context --skills-root .pi/skills <slug> --skill devrites-api-interface` (no workspace: `--out <path>`) bundles every file named below into one deduplicated read.
# devrites-api-interface: contract before implementation
When a slice crosses a boundary (FE/BE, service/service, module/module) or exposes a
public interface, define the contract first so both sides can proceed and the interface
stays stable.
## Define the contract first
- **Shape:** request/response or function signature; field names, types, optionality,
units. Follow the project's existing naming and conventions.
- **Status & errors:** success codes, error codes, error body shape, validation
messages. Errors are part of the contract, not an afterthought.
- **Semantics:** idempotency, pagination, ordering, nullability, side effects.
- **Versioning/compat:** is this new or a change to an existing contract? A breaking
change to an existing consumer is a user decision (and a drift event if unplanned).
## Stability principles
- Design for the caller. The interface should make the common case easy and the wrong
call hard.
- **Prefer addition over modification.** A new field is additive and optional; changing a
field's type or removing one is a breaking change. You can add later. You can't un-ship a
shape consumers already read (observable behavior is the contract: [`deprecation.md`](../devrites-lib/reference/standards/deprecation.md) Hyrum's law).
- **One-Version Rule.** Design as if only one version of this interface will ever exist:
extend the single contract rather than fork a v2 you then maintain in parallel. Forking
multiplies the surface and breeds diamond-dependency conflicts; bump a version only when an
addition genuinely can't stay backward-compatible.
- Match existing endpoints/modules in style: don't introduce a competing convention.
- **Validate at the boundary, and only there** (untrusted → trusted); don't trust
caller-supplied trust signals (IDs, roles). Validation does *not* belong between two internal
typed functions, on your own database's data, or in a utility already called by validated code.
A check inside the trusted core hides the bug in the boundary that should have caught it. A
third-party API response is external input: always untrusted. (Three-tier boundary:
[`security.md`](../devrites-lib/reference/standards/security.md); see [`security-review.md`](../rite-review/reference/security-review.md).)
## Type craft: make the wrong call unrepresentable
- **Brand your ids.** A bare `string`/`number` id is assignable to any other id, so the compiler
won't stop you passing a `userId` where a `taskId` is due. Give each a nominal brand
(`type TaskId = string & { readonly __brand: 'TaskId' }`) and the mix-up becomes a type error,
not a production incident.
- **Model variants as discriminated unions**, each state carrying only its own fields, so an
impossible combination can't be constructed in the first place.
## Doubt the contract
Before standing the interface, run `devrites-doubt`.
## Done when
The contract is complete only when **every** field carries a type + optionality + unit,
**every** success and error status code is enumerated with its error-body shape, the
`devrites-doubt` verdict is accept (on reject: revise the contract and re-doubt under
[the canonical retry contract](../devrites-lib/reference/standards/afk-hitl.md#retry-cap-no-progress-loops-and-self-resolve)
with caller repair and human-risk gates), and the
contract + rationale are recorded in `decisions.md`. A contract that pins only the
happy-path shape is not done.
## Enables the split
A clear contract lets `/rite-plan split` proceed: the backend slice can land against the
contract with a stub consumer; the frontend slice can build against a mock or the real
contract. Neither side blocks on the other.