Files
2026-04-18 22:04:00 +03:00

5.3 KiB
Raw Permalink Blame History

API Contract Template

A contract is the frozen, reviewed interface between two or more components. When task A produces a shared model, DTO, schema, event payload, or public API, and task B consumes it, they must not reverse-engineer each other's implementation — they must read the contract.

Save the filled contract at _docs/02_document/contracts/<component>/<name>.md. Reference it from the producing task's ## Contract section and from every consuming task's ## Dependencies section.


# Contract: [contract-name]

**Component**: [component-name]
**Producer task**: [TRACKER-ID] — [task filename]
**Consumer tasks**: [list of TRACKER-IDs or "TBD at decompose time"]
**Version**: 1.0.0
**Status**: [draft | frozen | deprecated]
**Last Updated**: [YYYY-MM-DD]

## Purpose

Short statement of what this contract represents and why it is shared (13 sentences).

## Shape

Choose ONE of the following shape forms per the contract type:

### For data models (DTO / schema / event)

```[language]
// language-native type definitions — e.g., Python dataclass, C# record, TypeScript interface, Rust struct, JSON Schema

For each field:

Field Type Required Description Constraints
id string (UUID) yes Unique identifier RFC 4122 v4
created_at datetime (ISO 8601 UTC) yes Creation timestamp
... ... ... ... ...

For function / method APIs

Name Signature Throws / Errors Blocking?
do_x (input: InputDto) -> Result<OutputDto, XError> XError::NotFound, XError::Invalid sync
... ... ... ...

For HTTP / RPC endpoints

Method Path Request body Response Status codes
POST /api/v1/resource CreateResource Resource 201, 400, 409
... ... ... ... ...

Invariants

Properties that MUST hold for every valid instance or every allowed interaction. These survive refactors.

  • Invariant 1: [statement]
  • Invariant 2: [statement]

Non-Goals

Things this contract intentionally does NOT cover. Helps prevent scope creep.

  • Not covered: [statement]

Versioning Rules

  • Breaking changes (field renamed/removed, type changed, required→optional flipped) require a new major version and a deprecation path for consumers.
  • Non-breaking additions (new optional field, new error variant consumers already tolerate) require a minor version bump.

Test Cases

Representative cases that both producer and consumer tests must cover. Keep short — this is the contract test surface, not an exhaustive suite.

Case Input Expected Notes
valid-minimal minimal valid instance accepted
invalid-missing-required missing id rejected with specific error
edge-case-x ... ...

Change Log

Version Date Change Author
1.0.0 YYYY-MM-DD Initial contract [agent/user]

---

## Decompose-skill rules for emitting contracts

A task is a **shared-models / shared-API task** when ANY of the following is true:

- The component spec lists it as a shared component (under `shared/*` in `module-layout.md`).
- The task's **Scope.Included** mentions any of: "public interface", "DTO", "schema", "event", "contract", "API endpoint", "shared model".
- The task is parented to a cross-cutting epic (`epic_type: cross-cutting`).
- The task is depended on by ≥2 other tasks across different components.

For every shared-models / shared-API task:

1. Create a contract file at `_docs/02_document/contracts/<component>/<name>.md` using this template.
2. Fill in Shape, Invariants, Non-Goals, Versioning Rules, and at least 3 Test Cases.
3. Add a mandatory `## Contract` section to the task spec that links to the contract file:

   ```markdown
   ## Contract

   This task produces/implements the contract at `_docs/02_document/contracts/<component>/<name>.md`.
   Consumers MUST read that file — not this task spec — to discover the interface.
  1. For every consuming task, add the contract path to its ## Dependencies section as a document dependency (not a task dependency):

    ### Document Dependencies
    - `_docs/02_document/contracts/<component>/<name>.md` — API contract produced by [TRACKER-ID].
    
  2. If the contract changes after it was frozen, the producer task must bump the Version and note the change in Change Log. Consumers referenced in the contract header must be notified (surface to user via Choose format).

Code-review-skill rules for verifying contracts

Phase 2 (Spec Compliance) adds a check:

  • For every task with a ## Contract section:
    • Verify the referenced contract file exists at the stated path.
    • Verify the implementation's public signatures (types, method shapes, endpoint paths) match the contract's Shape section.
    • If they diverge, emit a Spec-Gap finding with High severity.
  • For every consuming task's Document Dependencies that reference a contract:
    • Verify the consumer's imports / calls match the contract's Shape.
    • If they diverge, emit a Spec-Gap finding with High severity and a hint that either the contract or the consumer is drifting.