@sumrco/cli 0.3.0 → 0.3.2
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.
- package/ai/modules/kontract/resources/api-generation-standards.rf.md +83 -0
- package/ai/modules/kontract/resources/{configuration.rf.md → authoring/configuration.rf.md} +49 -11
- package/ai/modules/kontract/resources/authoring/design-profile/api-styles.rf.md +241 -0
- package/ai/modules/kontract/resources/authoring/design-profile/async-styles.rf.md +134 -0
- package/ai/modules/kontract/resources/authoring/design-profile/overview.md +64 -0
- package/ai/modules/kontract/resources/authoring/design-profile/schema-layout-styles.rf.md +356 -0
- package/ai/modules/kontract/resources/authoring/overview.md +56 -0
- package/ai/modules/kontract/resources/{schema-reuse.rf.md → authoring/schema-reuse.rf.md} +222 -46
- package/ai/modules/kontract/resources/{scope-and-splitting.rf.md → authoring/scope-and-splitting.rf.md} +113 -57
- package/ai/modules/kontract/resources/authoring/spec-layout.rf.md +492 -0
- package/ai/modules/kontract/resources/authoring/team-members/spec-author.tm.md +77 -0
- package/ai/modules/kontract/resources/{workflows/contract-change.wf.md → authoring/workflows/spec-change.wf.md} +21 -15
- package/ai/modules/kontract/resources/generated-output.rf.md +19 -14
- package/ai/modules/kontract/resources/openapi-sdk-generator-research.rf.md +17 -19
- package/ai/modules/kontract/resources/overview.md +115 -82
- package/ai/modules/kontract/resources/performance.rf.md +7 -7
- package/ai/modules/kontract/sumr.module.yaml +3 -0
- package/ai/modules/mission/sumr.module.yaml +6 -0
- package/ai/modules/playbook/resources/authoring/content-structure.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/cross-referencing.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/descriptions.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/extraction.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/flows.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/folder-structure.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/frontmatter.rf.md +4 -1
- package/ai/modules/playbook/resources/authoring/markdown.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/overview.md +1 -1
- package/ai/modules/playbook/resources/team-members/{playbook-technical-writer.tm.md → technical-writer.tm.md} +3 -2
- package/ai/modules/playbook/sumr.module.yaml +7 -2
- package/index.js +332 -276
- package/package.json +1 -1
- package/ai/modules/kontract/resources/language-sdk-generator-extension.rf.md +0 -62
- package/ai/modules/kontract/resources/openapi-generator-lessons.rf.md +0 -61
- package/ai/modules/kontract/resources/spec-layout.rf.md +0 -275
- package/ai/modules/kontract/resources/team-members/contract-author.tm.md +0 -60
package/package.json
CHANGED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
category: reference
|
|
3
|
-
name: language-sdk-generator-extension
|
|
4
|
-
title: Language SDK Generator Extension
|
|
5
|
-
description: "How Kontract should add future non-TypeScript SDK generators such as Java or Rust."
|
|
6
|
-
label: Language SDK Generator Extension
|
|
7
|
-
when: Researching or implementing a new Kontract SDK generator for another language
|
|
8
|
-
order: 47
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Language SDK Generator Extension
|
|
12
|
-
|
|
13
|
-
Kontract can add Java, Rust, or other SDK generators, but only as explicit
|
|
14
|
-
generator types after research and tests prove the output is useful.
|
|
15
|
-
|
|
16
|
-
## Current support
|
|
17
|
-
|
|
18
|
-
Implemented generators:
|
|
19
|
-
|
|
20
|
-
- `typescript-nestjs`
|
|
21
|
-
- `asyncapi-nats`
|
|
22
|
-
- `typescript-fetch`
|
|
23
|
-
- `typescript-axios`
|
|
24
|
-
- `typescript-angular`
|
|
25
|
-
- `typescript-models`
|
|
26
|
-
|
|
27
|
-
Java and Rust are not implemented yet. Config such as `type: java` or
|
|
28
|
-
`type: rust` must fail until a real generator exists.
|
|
29
|
-
|
|
30
|
-
## Add a new language generator
|
|
31
|
-
|
|
32
|
-
Use this sequence:
|
|
33
|
-
|
|
34
|
-
1. Research mature public generators for the target language and record lessons
|
|
35
|
-
in `resources/`.
|
|
36
|
-
2. Add the generator type to `src/types/contracts.types.ts`.
|
|
37
|
-
3. Add config parsing and allowed options in `src/lib/sumr-yaml.ts`.
|
|
38
|
-
4. Add dependency warnings in `src/cli/dependency-check.ts` only when generated
|
|
39
|
-
output requires runtime packages in the consumer repo.
|
|
40
|
-
5. Add a generator implementation under `src/generators/openapi/<language>/` or
|
|
41
|
-
a shared SDK emitter if the language can reuse one.
|
|
42
|
-
6. Wire generation planning in `src/cli/generate-plan.ts`.
|
|
43
|
-
7. Add tests that prove config parsing, output shape, unsafe-schema failures,
|
|
44
|
-
and generated file roots.
|
|
45
|
-
8. Update `README.md`, `docs/**`, `resources/**`, and regenerate AI resources
|
|
46
|
-
with `bun run sync`.
|
|
47
|
-
|
|
48
|
-
## Test coverage required
|
|
49
|
-
|
|
50
|
-
Every generator must have at least:
|
|
51
|
-
|
|
52
|
-
- a config parsing test;
|
|
53
|
-
- a direct generation test for expected root files;
|
|
54
|
-
- an edge-case test for reserved names or language keywords;
|
|
55
|
-
- query array serialization coverage for HTTP SDKs;
|
|
56
|
-
- enum and `additionalProperties` coverage where the language supports them;
|
|
57
|
-
- a rejection test for unsupported schema features such as unsafe polymorphism;
|
|
58
|
-
- a catalog coverage test so the documented generator list and implemented list
|
|
59
|
-
stay aligned.
|
|
60
|
-
|
|
61
|
-
Do not add a generator type first and fill behavior later. Unsupported language
|
|
62
|
-
targets should stay rejected until they can generate useful, validated output.
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
category: reference
|
|
3
|
-
name: openapi-generator-lessons
|
|
4
|
-
title: OpenAPI Generator Bug Lessons
|
|
5
|
-
description: "Hardening lessons Kontract applies from public OpenAPI Generator NestJS/TypeScript bug reports. Use when reviewing generated output risks, query parameters, inline schemas, and strict TypeScript compatibility."
|
|
6
|
-
label: OpenAPI Generator Lessons
|
|
7
|
-
when: Reviewing Kontract specs or generator changes for known OpenAPI/NestJS codegen failure modes
|
|
8
|
-
order: 45
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# OpenAPI Generator Bug Lessons
|
|
12
|
-
|
|
13
|
-
Kontract learns from public OpenAPI/NestJS generator bugs without inheriting their
|
|
14
|
-
architecture. These lessons are guardrails for spec authors, reviewers, and AI agents
|
|
15
|
-
working on generated contracts.
|
|
16
|
-
|
|
17
|
-
## Core lessons
|
|
18
|
-
|
|
19
|
-
- **Preserve query parameter semantics.** Optional query params stay optional, array query
|
|
20
|
-
params serialize as repeated keys, and enum query params use generated enum symbols instead
|
|
21
|
-
of raw literal imports.
|
|
22
|
-
- **Do not let wire names become unsafe local variables.** Parameter names such as `from`,
|
|
23
|
-
`class`, and `default` must remain valid wire keys while generated local identifiers are
|
|
24
|
-
safe TypeScript names.
|
|
25
|
-
- **Prefer component `$ref` schemas over anonymous inline operation models.** Kontract rejects
|
|
26
|
-
inline request/response schemas because anonymous model naming commonly causes duplicate
|
|
27
|
-
`InlineObject` outputs and unstable imports.
|
|
28
|
-
- **Generate maps deliberately.** `additionalProperties` map schemas must preserve named
|
|
29
|
-
properties and typed catch-all/index-signature values consistently across Zod, DTOs, models,
|
|
30
|
-
and SDK output. Unsupported `oneOf`, `anyOf`, `not`, and discriminators should produce clear
|
|
31
|
-
errors instead of partially generated code with missing symbols such as `AnyType` or
|
|
32
|
-
`InnerEnum`.
|
|
33
|
-
- **Keep NestJS ownership boundaries clean.** Kontract emits contracts, DTOs, models, swagger
|
|
34
|
-
metadata, and SDK clients. Application modules, controllers, providers, and DI wiring stay in
|
|
35
|
-
the consuming NestJS app.
|
|
36
|
-
- **Compile generated code under strict TypeScript assumptions.** Generated output should avoid
|
|
37
|
-
dangling imports, deprecated Nest HTTP client imports, stale `basePath` globals, `Map` headers
|
|
38
|
-
where records are expected, and framework symbols that were never emitted.
|
|
39
|
-
- **Stay Bun-native.** Kontract does not depend on Java, Docker images, downloaded generator
|
|
40
|
-
binaries, or template folders at generation time.
|
|
41
|
-
|
|
42
|
-
## Spec authoring rules
|
|
43
|
-
|
|
44
|
-
- Put reusable request/response bodies, parameters, enums, and object fragments under
|
|
45
|
-
`components` and reference them with `$ref`.
|
|
46
|
-
- Encode validation constraints in the OpenAPI schema (`minLength`, `maxLength`, `minimum`,
|
|
47
|
-
`maximum`, `pattern`, `format`) so DTO/Zod output can enforce them.
|
|
48
|
-
- Use `additionalProperties` when the payload is intentionally map-shaped. Prefer typed map values
|
|
49
|
-
over `additionalProperties: true`; Kontract preserves named fields and emits a safe unknown
|
|
50
|
-
catch-all when the spec intentionally allows arbitrary values.
|
|
51
|
-
- For repeated query values, use `type: array` with scalar `items`; generated SDKs must not
|
|
52
|
-
collapse values into comma-separated strings.
|
|
53
|
-
|
|
54
|
-
## Reviewer checklist
|
|
55
|
-
|
|
56
|
-
- Generated files include the auto-generated header and are not hand-edited.
|
|
57
|
-
- Query DTOs and SDK request types preserve optionality from the spec.
|
|
58
|
-
- No generated file contains `any`, `AnyType`, `InlineObject`, `InnerEnum`, `queryParameters`,
|
|
59
|
-
deprecated `HttpService`, stale `basePath`, or unsafe `apiKeys` access.
|
|
60
|
-
- Operation schemas reference named components instead of inline request/response objects.
|
|
61
|
-
- Unsupported schema features fail before any consumer repo is left with partial broken output.
|
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
category: reference
|
|
3
|
-
name: spec-layout
|
|
4
|
-
title: Spec File Layout
|
|
5
|
-
description: "Required folder and file conventions for Kontract OpenAPI/AsyncAPI source specs."
|
|
6
|
-
label: Spec Layout
|
|
7
|
-
when: Creating or moving API spec files, adding a shared base spec, or debugging why a spec is not picked up
|
|
8
|
-
order: 10
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Spec File Layout
|
|
12
|
-
|
|
13
|
-
Kontract discovers specs by filename convention under the configured schema
|
|
14
|
-
directory (default `schema/`).
|
|
15
|
-
|
|
16
|
-
```text
|
|
17
|
-
schema/
|
|
18
|
-
recipes.openapi.yml ← one OpenAPI doc per service/domain
|
|
19
|
-
recipes.asyncapi.yml ← one AsyncAPI doc per service/domain
|
|
20
|
-
recipes.schema.yml ← neutral suffix; detected by openapi:/asyncapi:
|
|
21
|
-
base.yml ← shared components, referenced via $ref
|
|
22
|
-
bookstore/
|
|
23
|
-
bookstore.openapi.yml ← root entrypoint
|
|
24
|
-
bookstore.asyncapi.yml ← root entrypoint
|
|
25
|
-
paths/catalog.yml ← OpenAPI path fragments
|
|
26
|
-
messages/events.yml ← AsyncAPI channel/message fragments
|
|
27
|
-
models/shared.yml ← protocol-neutral model fragments
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Rules
|
|
31
|
-
|
|
32
|
-
- OpenAPI specs end in `*.openapi.yml` / `*.openapi.yaml`.
|
|
33
|
-
- AsyncAPI specs end in `*.asyncapi.yml` / `*.asyncapi.yaml`.
|
|
34
|
-
- Use `*.schema.yml` / `*.schema.yaml` when a domain folder already makes the
|
|
35
|
-
protocol obvious less useful than the business surface name. Kontract reads
|
|
36
|
-
the file marker and treats `openapi:` as OpenAPI and `asyncapi:` as AsyncAPI.
|
|
37
|
-
- Discovery is recursive; `base.yml` is skipped as an entry point.
|
|
38
|
-
- Service output paths mirror nested spec paths under the configured source
|
|
39
|
-
input directory.
|
|
40
|
-
- A root `*.openapi.yml` or `*.asyncapi.yml` may reference plain `.yml`
|
|
41
|
-
fragments for paths, messages, parameters, and schemas. Kontract bundles the
|
|
42
|
-
root before generation when it finds external `$ref` links.
|
|
43
|
-
- OpenAPI and AsyncAPI roots may share neutral model fragments when the shapes
|
|
44
|
-
mean the same thing for HTTP and messaging. Keep protocol-specific path,
|
|
45
|
-
operation, parameter, channel, and message metadata in separate fragments.
|
|
46
|
-
- Nested `*.schema.yml` files are grouped by their first folder. This supports a
|
|
47
|
-
DDD layout where the folder is the domain and each file is a subdomain surface:
|
|
48
|
-
|
|
49
|
-
```text
|
|
50
|
-
schema/
|
|
51
|
-
recipes/
|
|
52
|
-
catalog.schema.yml ← OpenAPI
|
|
53
|
-
publishing.schema.yml ← AsyncAPI
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Both files generate under `contracts/recipes/`.
|
|
57
|
-
- Use nested domain/subdomain paths when one root file would mix independently
|
|
58
|
-
owned API surfaces; see the scope and splitting reference for line-count
|
|
59
|
-
thresholds and naming rules.
|
|
60
|
-
- Use comments only as editor navigation markers. Comments may label groups such
|
|
61
|
-
as `Catalog paths` or `Response schemas`, but they must not explain endpoint
|
|
62
|
-
behavior or replace `summary` / `description`.
|
|
63
|
-
- Share common schemas through `$ref` into `base.yml`. Do **not** duplicate
|
|
64
|
-
schemas across specs and do **not** merge by hand-mutating parsed JSON.
|
|
65
|
-
- Prefer a `schema/shared/` folder for cross-domain components such as common
|
|
66
|
-
parameters, error responses, pagination, scalar constraints, response envelope
|
|
67
|
-
fragments, schedules, and reusable config objects.
|
|
68
|
-
- The NATS namespace comes from the AsyncAPI `info.title`, not the filename —
|
|
69
|
-
set `info.title` deliberately.
|
|
70
|
-
- Multi-file specs are bundled automatically (OpenAPI via Redocly core in-process
|
|
71
|
-
with CLI fallback, AsyncAPI via `@asyncapi/cli bundle`); keep `$ref` paths
|
|
72
|
-
repo-relative.
|
|
73
|
-
|
|
74
|
-
## Split root-entrypoint layout
|
|
75
|
-
|
|
76
|
-
Use this layout when one product domain should generate as one contract package,
|
|
77
|
-
but the root files are getting too large:
|
|
78
|
-
|
|
79
|
-
```text
|
|
80
|
-
schema/
|
|
81
|
-
bookstore/
|
|
82
|
-
bookstore.openapi.yml
|
|
83
|
-
bookstore.asyncapi.yml
|
|
84
|
-
components/
|
|
85
|
-
parameters.yml
|
|
86
|
-
paths/
|
|
87
|
-
books.yml
|
|
88
|
-
authors.yml
|
|
89
|
-
messages/
|
|
90
|
-
books.yml
|
|
91
|
-
authors.yml
|
|
92
|
-
models/
|
|
93
|
-
shared.yml
|
|
94
|
-
books.yml
|
|
95
|
-
authors.yml
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
The root files stay small and readable. Fragment files are plain `.yml` because
|
|
99
|
-
they are not standalone OpenAPI or AsyncAPI documents.
|
|
100
|
-
|
|
101
|
-
If a root file needs many visual section markers to stay readable, split the
|
|
102
|
-
internals into domain/subdomain fragments before adding more comments.
|
|
103
|
-
|
|
104
|
-
```yaml
|
|
105
|
-
# schema/bookstore/bookstore.openapi.yml
|
|
106
|
-
openapi: 3.0.3
|
|
107
|
-
info:
|
|
108
|
-
title: Bookstore Contracts
|
|
109
|
-
version: 1.0.0
|
|
110
|
-
paths:
|
|
111
|
-
/books:
|
|
112
|
-
$ref: ./paths/books.yml#/paths/~1books
|
|
113
|
-
components:
|
|
114
|
-
schemas:
|
|
115
|
-
Book:
|
|
116
|
-
$ref: ./models/books.yml#/Book
|
|
117
|
-
PaginatedBooks:
|
|
118
|
-
$ref: ./models/books.yml#/PaginatedBooks
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
```yaml
|
|
122
|
-
# schema/bookstore/paths/books.yml
|
|
123
|
-
paths:
|
|
124
|
-
/books:
|
|
125
|
-
get:
|
|
126
|
-
operationId: listBooks
|
|
127
|
-
responses:
|
|
128
|
-
"200":
|
|
129
|
-
description: Paginated book list.
|
|
130
|
-
content:
|
|
131
|
-
application/json:
|
|
132
|
-
schema:
|
|
133
|
-
$ref: ../models/books.yml#/PaginatedBooks
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
```yaml
|
|
137
|
-
# schema/bookstore/bookstore.asyncapi.yml
|
|
138
|
-
asyncapi: 3.0.0
|
|
139
|
-
info:
|
|
140
|
-
title: Bookstore
|
|
141
|
-
version: 1.0.0
|
|
142
|
-
channels:
|
|
143
|
-
listBooks:
|
|
144
|
-
$ref: ./messages/books.yml#/channels/listBooks
|
|
145
|
-
listBooksReply:
|
|
146
|
-
$ref: ./messages/books.yml#/channels/listBooksReply
|
|
147
|
-
operations:
|
|
148
|
-
listBooks:
|
|
149
|
-
$ref: ./messages/books.yml#/operations/listBooks
|
|
150
|
-
components:
|
|
151
|
-
messages:
|
|
152
|
-
ListBooksQuery:
|
|
153
|
-
$ref: ./messages/books.yml#/messages/ListBooksQuery
|
|
154
|
-
PaginatedBooksReply:
|
|
155
|
-
$ref: ./messages/books.yml#/messages/PaginatedBooksReply
|
|
156
|
-
schemas:
|
|
157
|
-
ListBooksQuery:
|
|
158
|
-
$ref: ./models/books.yml#/ListBooksQuery
|
|
159
|
-
PaginatedBooks:
|
|
160
|
-
$ref: ./models/books.yml#/PaginatedBooks
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
```yaml
|
|
164
|
-
# schema/bookstore/messages/books.yml
|
|
165
|
-
channels:
|
|
166
|
-
listBooks:
|
|
167
|
-
address: qry.bookstore.books.list
|
|
168
|
-
messages:
|
|
169
|
-
listBooksQuery:
|
|
170
|
-
$ref: ./books.yml#/messages/ListBooksQuery
|
|
171
|
-
listBooksReply:
|
|
172
|
-
address: qry.bookstore.books.list.reply
|
|
173
|
-
messages:
|
|
174
|
-
paginatedBooksReply:
|
|
175
|
-
$ref: ./books.yml#/messages/PaginatedBooksReply
|
|
176
|
-
operations:
|
|
177
|
-
listBooks:
|
|
178
|
-
action: receive
|
|
179
|
-
channel:
|
|
180
|
-
$ref: "#/channels/listBooks"
|
|
181
|
-
messages:
|
|
182
|
-
- $ref: "#/channels/listBooks/messages/listBooksQuery"
|
|
183
|
-
reply:
|
|
184
|
-
channel:
|
|
185
|
-
$ref: "#/channels/listBooksReply"
|
|
186
|
-
messages:
|
|
187
|
-
- $ref: "#/channels/listBooksReply/messages/paginatedBooksReply"
|
|
188
|
-
messages:
|
|
189
|
-
ListBooksQuery:
|
|
190
|
-
payload:
|
|
191
|
-
$ref: ../models/books.yml#/ListBooksQuery
|
|
192
|
-
PaginatedBooksReply:
|
|
193
|
-
payload:
|
|
194
|
-
$ref: ../models/books.yml#/PaginatedBooks
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
Shared schemas can be referenced by both roots when they carry the same business
|
|
198
|
-
meaning:
|
|
199
|
-
|
|
200
|
-
```yaml
|
|
201
|
-
# schema/bookstore/models/shared.yml
|
|
202
|
-
BookSlug:
|
|
203
|
-
type: string
|
|
204
|
-
minLength: 1
|
|
205
|
-
maxLength: 120
|
|
206
|
-
pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
```yaml
|
|
210
|
-
# schema/bookstore/models/books.yml
|
|
211
|
-
Book:
|
|
212
|
-
type: object
|
|
213
|
-
required: [id, slug, title]
|
|
214
|
-
properties:
|
|
215
|
-
id:
|
|
216
|
-
type: string
|
|
217
|
-
format: uuid
|
|
218
|
-
slug:
|
|
219
|
-
$ref: ./shared.yml#/BookSlug
|
|
220
|
-
title:
|
|
221
|
-
type: string
|
|
222
|
-
minLength: 1
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
Do not put graph, routing, or protocol behavior into shared model fragments.
|
|
226
|
-
Share only business payload shapes.
|
|
227
|
-
|
|
228
|
-
## OpenAPI authoring rules
|
|
229
|
-
|
|
230
|
-
- Put reusable HTTP payloads in `components.schemas`.
|
|
231
|
-
- Operation request/response schemas should reference components with `$ref`.
|
|
232
|
-
Inline operation schemas are rejected so generated DTO/model names stay stable.
|
|
233
|
-
- Use operation `summary` to name the action. Use `description` to explain
|
|
234
|
-
outcome, scope, caller context, constraints, or next steps; do not repeat the
|
|
235
|
-
summary in sentence form.
|
|
236
|
-
- Avoid tag echo. If the API docs already show a tag such as `Playbook` or
|
|
237
|
-
`Accounts`, omit that word from the summary unless the operation would become
|
|
238
|
-
ambiguous.
|
|
239
|
-
- Route public or developer-facing `summary`, `description`, parameter, schema,
|
|
240
|
-
and response text through the repo's copywriter/microcopy standard before
|
|
241
|
-
validating.
|
|
242
|
-
- Prefer explicit object schemas over anonymous nested shapes when a payload is
|
|
243
|
-
shared by multiple operations.
|
|
244
|
-
- If multiple responses repeat the same envelope fields, extract the envelope
|
|
245
|
-
fragment and compose concrete responses with supported object `allOf`.
|
|
246
|
-
- If multiple schemas repeat the same regex or scalar validation, extract a
|
|
247
|
-
named scalar component and reference it.
|
|
248
|
-
- Use stable `operationId` values. They become Swagger metadata constants such
|
|
249
|
-
as `SWG_LIST_RECIPES`.
|
|
250
|
-
- Unsupported composition features (`oneOf`, `anyOf`, `not`, `discriminator`)
|
|
251
|
-
must either be modeled differently or implemented in Kontract before use.
|
|
252
|
-
|
|
253
|
-
## AsyncAPI operation classification
|
|
254
|
-
|
|
255
|
-
| AsyncAPI shape | Generated client kind |
|
|
256
|
-
|---------------------|-----------------------|
|
|
257
|
-
| `receive` + `reply` | Query |
|
|
258
|
-
| `receive` | Command |
|
|
259
|
-
| `send` | Event |
|
|
260
|
-
|
|
261
|
-
Run `sumr kontract validate` after any layout change to confirm specs still
|
|
262
|
-
resolve before generating.
|
|
263
|
-
|
|
264
|
-
## AsyncAPI copy rules
|
|
265
|
-
|
|
266
|
-
AsyncAPI `title`, `summary`, and `description` fields can appear in generated
|
|
267
|
-
docs, SDK docs, and AI answers. Write them with the same copy gate as OpenAPI:
|
|
268
|
-
|
|
269
|
-
- `title` names the message or operation.
|
|
270
|
-
- `summary` states the job or event in one concise sentence.
|
|
271
|
-
- `description` adds context only when the outcome, constraint, or event
|
|
272
|
-
semantics need more detail.
|
|
273
|
-
- Do not repeat the channel, operation id, schema key, or title in the summary.
|
|
274
|
-
- Keep transport terms such as subject, payload, NATS, command, and query only
|
|
275
|
-
when the reader needs that exact implementation detail.
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
category: team-member
|
|
3
|
-
name: contract-author
|
|
4
|
-
title: Contract Author
|
|
5
|
-
description: "Owns API spec authoring and Kontract regeneration discipline. Use when changing OpenAPI/AsyncAPI specs, validating, regenerating, or reviewing generated contract diffs."
|
|
6
|
-
modelTier: reasoning
|
|
7
|
-
access: write
|
|
8
|
-
channels:
|
|
9
|
-
codex:
|
|
10
|
-
sandbox_mode: workspace-write
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# Contract Author
|
|
14
|
-
|
|
15
|
-
You own the API contract source of truth for this repo. You change YAML specs
|
|
16
|
-
and let Kontract generate the TypeScript — you never hand-write or hand-patch
|
|
17
|
-
generated contracts.
|
|
18
|
-
|
|
19
|
-
Apply the generated **sumr-kontract-usage** skill, plus the configuration,
|
|
20
|
-
spec-layout, schema-reuse, scope-and-splitting, and generated-output references,
|
|
21
|
-
before acting.
|
|
22
|
-
|
|
23
|
-
## Responsibilities
|
|
24
|
-
|
|
25
|
-
- Translate API requirements into OpenAPI/AsyncAPI specs under `schema/`.
|
|
26
|
-
- After writing or updating any `*.openapi.yml` / `*.asyncapi.yml` file, review
|
|
27
|
-
it against Kontract reuse, layout, and generation rules before validating.
|
|
28
|
-
- Route changed public or developer-facing summaries, descriptions, parameter
|
|
29
|
-
descriptions, response descriptions, message titles, and message summaries
|
|
30
|
-
through the repo's copywriter/microcopy standard before generation.
|
|
31
|
-
- Keep shared shapes in shared component files and reference them with `$ref`.
|
|
32
|
-
- Keep specs domain-aligned and reviewable: use domain/subdomain paths, split
|
|
33
|
-
oversized files at documented thresholds, and avoid generic `common` buckets
|
|
34
|
-
for unrelated concepts.
|
|
35
|
-
- Use comments only as visual editor landmarks. Do not explain endpoint behavior
|
|
36
|
-
with comments; use OpenAPI/AsyncAPI descriptions for that.
|
|
37
|
-
- Name schemas from domain meaning first, using operation-specific response
|
|
38
|
-
names only when the shape belongs to one operation.
|
|
39
|
-
- Proactively spot duplicated envelope fields, pagination metadata, error
|
|
40
|
-
schemas, path/query params, regex scalar constraints, schedules, and config
|
|
41
|
-
objects before generating.
|
|
42
|
-
- Prefer supported object `allOf` composition when a concrete response extends
|
|
43
|
-
a shared base envelope.
|
|
44
|
-
- Run `sumr kontract validate` then `sumr kontract generate` for every change.
|
|
45
|
-
- Review the generated diff for correctness and unintended breakage.
|
|
46
|
-
- If a generated diff creates many near-identical DTO/model files, pause and
|
|
47
|
-
propose a spec-level shared component refactor.
|
|
48
|
-
- Keep spec + regenerated output committed together.
|
|
49
|
-
- When generated files are missing, check `sumr.yaml` target options and the
|
|
50
|
-
installed `SUMR Kontract module` version before changing application code.
|
|
51
|
-
|
|
52
|
-
## Boundaries
|
|
53
|
-
|
|
54
|
-
- Never edit files under the generated `contracts/` output.
|
|
55
|
-
- Never hand-write Zod schemas, DTOs, NATS subjects, or clients that Kontract owns.
|
|
56
|
-
- Do not introduce a second source of truth; the spec is authoritative.
|
|
57
|
-
- Do not over-share unrelated concepts only because their current fields look
|
|
58
|
-
similar; shared components must have the same product meaning and owner.
|
|
59
|
-
- Flag breaking contract changes for human review before commit.
|
|
60
|
-
- Scope `--clean` to the intended source/target in consumer repos.
|