@sumrco/cli 0.1.0
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/README.md +36 -0
- package/ai/modules/kontract/resources/configuration.rf.md +123 -0
- package/ai/modules/kontract/resources/generated-output.rf.md +179 -0
- package/ai/modules/kontract/resources/openapi-generator-lessons.rf.md +61 -0
- package/ai/modules/kontract/resources/overview.md +115 -0
- package/ai/modules/kontract/resources/performance.rf.md +90 -0
- package/ai/modules/kontract/resources/schema-reuse.rf.md +233 -0
- package/ai/modules/kontract/resources/scope-and-splitting.rf.md +147 -0
- package/ai/modules/kontract/resources/spec-layout.rf.md +69 -0
- package/ai/modules/kontract/resources/team-members/contract-author.tm.md +52 -0
- package/ai/modules/kontract/resources/workflows/contract-change.wf.md +60 -0
- package/ai/modules/kontract/sumr.module.yaml +42 -0
- package/ai/modules/mission/resources/flow-actions.rf.md +40 -0
- package/ai/modules/mission/resources/flow-config.rf.md +39 -0
- package/ai/modules/mission/resources/flow-safety-boundaries.rf.md +23 -0
- package/ai/modules/mission/resources/overview.md +69 -0
- package/ai/modules/mission/resources/stage-closeout.rf.md +21 -0
- package/ai/modules/mission/resources/stage-delivery.rf.md +36 -0
- package/ai/modules/mission/resources/stage-intake.rf.md +39 -0
- package/ai/modules/mission/resources/stage-planning.rf.md +21 -0
- package/ai/modules/mission/resources/stage-pull-request.rf.md +50 -0
- package/ai/modules/mission/resources/stage-quality.rf.md +22 -0
- package/ai/modules/mission/resources/team-members/delivery-lead.tm.md +39 -0
- package/ai/modules/mission/resources/team-members/implementer.tm.md +25 -0
- package/ai/modules/mission/resources/team-members/planner.tm.md +102 -0
- package/ai/modules/mission/resources/team-members/pr-writer.tm.md +57 -0
- package/ai/modules/mission/resources/team-members/product-owner.tm.md +37 -0
- package/ai/modules/mission/resources/team-members/quality-lead.tm.md +34 -0
- package/ai/modules/mission/resources/workflows/daily-triage.wf.md +117 -0
- package/ai/modules/mission/resources/workflows/full-delivery.wf.md +18 -0
- package/ai/modules/mission/resources/workflows/mission-cycle.wf.md +30 -0
- package/ai/modules/mission/resources/workflows/planning-only.wf.md +68 -0
- package/ai/modules/mission/resources/workflows/pr-assist.wf.md +21 -0
- package/ai/modules/mission/resources/workflows/standard-delivery.wf.md +18 -0
- package/ai/modules/mission/sumr.module.yaml +78 -0
- package/ai/modules/playbook/resources/authoring/content-structure.rf.md +148 -0
- package/ai/modules/playbook/resources/authoring/cross-referencing.rf.md +57 -0
- package/ai/modules/playbook/resources/authoring/descriptions.rf.md +71 -0
- package/ai/modules/playbook/resources/authoring/extraction.rf.md +81 -0
- package/ai/modules/playbook/resources/authoring/flows.rf.md +55 -0
- package/ai/modules/playbook/resources/authoring/folder-structure.rf.md +148 -0
- package/ai/modules/playbook/resources/authoring/frontmatter.rf.md +251 -0
- package/ai/modules/playbook/resources/authoring/markdown.rf.md +108 -0
- package/ai/modules/playbook/resources/authoring/overview.md +213 -0
- package/ai/modules/playbook/resources/team-members/playbook-technical-writer.tm.md +31 -0
- package/ai/modules/playbook/sumr.module.yaml +47 -0
- package/ai/registry.json +18 -0
- package/bin/_sumr +4 -0
- package/bin/sumr +7 -0
- package/index.js +410 -0
- package/package.json +52 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: reference
|
|
3
|
+
name: schema-reuse
|
|
4
|
+
title: Schema Reuse and Shared Components
|
|
5
|
+
description: "How to author OpenAPI/AsyncAPI specs with reusable shared components, $ref, and safe composition so Kontract output stays consistent and avoids copy-pasted contract drift."
|
|
6
|
+
label: Schema Reuse
|
|
7
|
+
when: Adding repeated fields, response envelopes, pagination, errors, schedules, config objects, or reviewing generated diffs with duplicated DTO/model shapes
|
|
8
|
+
order: 12
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Schema Reuse and Shared Components
|
|
12
|
+
|
|
13
|
+
Kontract works best when the spec is designed like a product API, not like a
|
|
14
|
+
collection of copied YAML snippets. If the same concept appears in multiple
|
|
15
|
+
operations or services, define it once and reference it with `$ref`.
|
|
16
|
+
|
|
17
|
+
This reduces drift in the source specs immediately. It also gives Kontract a
|
|
18
|
+
clear path to emit more shared generated code as the generator evolves.
|
|
19
|
+
|
|
20
|
+
## What to share
|
|
21
|
+
|
|
22
|
+
Prefer shared components for concepts that mean the same thing everywhere:
|
|
23
|
+
|
|
24
|
+
- scalar primitives: UUIDs, ISO dates, slugs, URLs, MIME types, time strings;
|
|
25
|
+
- path/query parameters: `id`, `recipeId`, pagination, date ranges;
|
|
26
|
+
- standard error responses and error body schemas;
|
|
27
|
+
- pagination metadata;
|
|
28
|
+
- common response envelope fields such as `success`, `timestamp`, `path`, and
|
|
29
|
+
optional `message`;
|
|
30
|
+
- weekly schedules and reusable time-slot shapes;
|
|
31
|
+
- repeated configuration objects, such as measurement units, recipe step labels,
|
|
32
|
+
display colors, notification settings, or payment settings when they truly
|
|
33
|
+
share semantics.
|
|
34
|
+
|
|
35
|
+
Example shared scalar and parameter file:
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
# schema/shared/common.yml
|
|
39
|
+
components:
|
|
40
|
+
schemas:
|
|
41
|
+
UuidString:
|
|
42
|
+
type: string
|
|
43
|
+
format: uuid
|
|
44
|
+
ImageMimeType:
|
|
45
|
+
type: string
|
|
46
|
+
pattern: '^image\/(jpeg|png|webp|gif)$'
|
|
47
|
+
PaginationMeta:
|
|
48
|
+
type: object
|
|
49
|
+
required: [page, pageSize, pageCount, total]
|
|
50
|
+
properties:
|
|
51
|
+
page:
|
|
52
|
+
type: integer
|
|
53
|
+
minimum: 1
|
|
54
|
+
pageSize:
|
|
55
|
+
type: integer
|
|
56
|
+
minimum: 1
|
|
57
|
+
pageCount:
|
|
58
|
+
type: integer
|
|
59
|
+
minimum: 0
|
|
60
|
+
total:
|
|
61
|
+
type: integer
|
|
62
|
+
minimum: 0
|
|
63
|
+
parameters:
|
|
64
|
+
id:
|
|
65
|
+
name: id
|
|
66
|
+
in: path
|
|
67
|
+
required: true
|
|
68
|
+
schema:
|
|
69
|
+
$ref: '#/components/schemas/UuidString'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Use those components from service specs:
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
parameters:
|
|
76
|
+
- $ref: ../shared/common.yml#/components/parameters/id
|
|
77
|
+
content:
|
|
78
|
+
application/json:
|
|
79
|
+
schema:
|
|
80
|
+
$ref: ../shared/common.yml#/components/schemas/ImageMimeType
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Response envelopes
|
|
84
|
+
|
|
85
|
+
If every endpoint repeats the same envelope fields, do not retype them in every
|
|
86
|
+
schema. Put the shared part in a component and compose concrete responses with
|
|
87
|
+
`allOf`.
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
# schema/shared/common.yml
|
|
91
|
+
components:
|
|
92
|
+
schemas:
|
|
93
|
+
SuccessResponseBase:
|
|
94
|
+
type: object
|
|
95
|
+
required: [success, timestamp, path]
|
|
96
|
+
properties:
|
|
97
|
+
success:
|
|
98
|
+
type: boolean
|
|
99
|
+
timestamp:
|
|
100
|
+
type: string
|
|
101
|
+
format: date-time
|
|
102
|
+
path:
|
|
103
|
+
type: string
|
|
104
|
+
message:
|
|
105
|
+
type: string
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
# schema/recipes/catalog.openapi.yml
|
|
110
|
+
components:
|
|
111
|
+
schemas:
|
|
112
|
+
RecipesFindOneResponse:
|
|
113
|
+
allOf:
|
|
114
|
+
- $ref: ../shared/common.yml#/components/schemas/SuccessResponseBase
|
|
115
|
+
- type: object
|
|
116
|
+
required: [data]
|
|
117
|
+
properties:
|
|
118
|
+
data:
|
|
119
|
+
$ref: '#/components/schemas/RecipeResponse'
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use the same pattern for paginated responses:
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
components:
|
|
126
|
+
schemas:
|
|
127
|
+
RecipesFindAllResponse:
|
|
128
|
+
allOf:
|
|
129
|
+
- $ref: ../shared/common.yml#/components/schemas/SuccessResponseBase
|
|
130
|
+
- type: object
|
|
131
|
+
required: [data]
|
|
132
|
+
properties:
|
|
133
|
+
data:
|
|
134
|
+
type: array
|
|
135
|
+
items:
|
|
136
|
+
$ref: '#/components/schemas/RecipeResponse'
|
|
137
|
+
meta:
|
|
138
|
+
$ref: ../shared/common.yml#/components/schemas/PaginationMeta
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Kontract supports object `allOf` composition by flattening supported object refs
|
|
142
|
+
and inline object parts. Today this mainly reduces YAML duplication and contract
|
|
143
|
+
semantic drift. It may still emit concrete generated DTO/model properties per
|
|
144
|
+
response until the generator grows preserved composition or shared-output
|
|
145
|
+
emission.
|
|
146
|
+
|
|
147
|
+
## Schedules and repeated nested objects
|
|
148
|
+
|
|
149
|
+
If several features define the same day-of-week schedule or time-slot object,
|
|
150
|
+
share the object definitions instead of duplicating each day shape.
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
# schema/shared/scheduling.yml
|
|
154
|
+
components:
|
|
155
|
+
schemas:
|
|
156
|
+
WeeklyTimeSlot:
|
|
157
|
+
type: object
|
|
158
|
+
required: [from, to]
|
|
159
|
+
properties:
|
|
160
|
+
from:
|
|
161
|
+
type: string
|
|
162
|
+
pattern: '^(0[6-9]|1\d|2[0-3]):[0-5]\d$'
|
|
163
|
+
to:
|
|
164
|
+
type: string
|
|
165
|
+
pattern: '^(0[6-9]|1\d|2[0-3]):[0-5]\d$'
|
|
166
|
+
WeeklySchedule:
|
|
167
|
+
type: object
|
|
168
|
+
properties:
|
|
169
|
+
sunday:
|
|
170
|
+
type: array
|
|
171
|
+
items:
|
|
172
|
+
$ref: '#/components/schemas/WeeklyTimeSlot'
|
|
173
|
+
monday:
|
|
174
|
+
type: array
|
|
175
|
+
items:
|
|
176
|
+
$ref: '#/components/schemas/WeeklyTimeSlot'
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Then service-specific schedules can reference or compose those shared pieces.
|
|
180
|
+
|
|
181
|
+
## Review checklist
|
|
182
|
+
|
|
183
|
+
After writing or updating any `*.openapi.yml` or `*.asyncapi.yml` file, review
|
|
184
|
+
the spec before running generation. Actively look for these smells:
|
|
185
|
+
|
|
186
|
+
- the same `success/timestamp/path/message` fields repeated in many response
|
|
187
|
+
schemas;
|
|
188
|
+
- identical pagination `meta` objects or `PaginationMeta` definitions copied
|
|
189
|
+
across services instead of referencing a shared component;
|
|
190
|
+
- many `id` parameters declared inline instead of referencing a shared
|
|
191
|
+
parameter;
|
|
192
|
+
- inline UUID, date, date-time, URL, slug, or enum-like scalar constraints that
|
|
193
|
+
already exist in a shared component;
|
|
194
|
+
- identical regex patterns copied into multiple schemas;
|
|
195
|
+
- repeated day-of-week schedule structures;
|
|
196
|
+
- error response schemas or problem-details bodies copied instead of referencing
|
|
197
|
+
shared responses;
|
|
198
|
+
- event envelopes or AsyncAPI reply wrappers copied with the same product
|
|
199
|
+
meaning;
|
|
200
|
+
- generated diffs adding many near-identical DTO/model files after a small API
|
|
201
|
+
change.
|
|
202
|
+
|
|
203
|
+
When you see a smell, propose a shared component before generating.
|
|
204
|
+
|
|
205
|
+
## When not to share
|
|
206
|
+
|
|
207
|
+
Do not share only because two shapes currently look alike. Keep separate
|
|
208
|
+
components when:
|
|
209
|
+
|
|
210
|
+
- endpoints have different validation rules or lifecycle/backwards-compatibility
|
|
211
|
+
needs;
|
|
212
|
+
- a request DTO and response DTO intentionally differ, even if fields overlap;
|
|
213
|
+
- names would become vague (`CommonThing`, `BaseData`, `GenericConfig`);
|
|
214
|
+
- sharing would force unrelated teams/domains to coordinate every future change.
|
|
215
|
+
|
|
216
|
+
A good shared component has a clear product meaning and a stable owner.
|
|
217
|
+
|
|
218
|
+
## Safe workflow
|
|
219
|
+
|
|
220
|
+
1. Move the repeated shape into `schema/shared/*.yml` or a domain-level shared
|
|
221
|
+
component.
|
|
222
|
+
2. Replace duplicated schemas/parameters/responses with `$ref`.
|
|
223
|
+
3. Use supported `allOf` object composition when a concrete response extends a
|
|
224
|
+
shared base.
|
|
225
|
+
4. Run `sumr kontract validate`.
|
|
226
|
+
5. Run a scoped generation first, for example:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
sumr kontract generate --source api --target backend --specific recipes/catalog
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
6. Review both the spec diff and generated diff. If generated output changed in
|
|
233
|
+
unrelated domains, stop and investigate before committing.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: reference
|
|
3
|
+
name: scope-and-splitting
|
|
4
|
+
title: Scope, Size, and Splitting
|
|
5
|
+
description: "How to keep Kontract specs and generator code small, domain-aligned, and reviewable with explicit line-count budgets and split triggers."
|
|
6
|
+
label: Scope and Splitting
|
|
7
|
+
when: Reviewing large specs or code files, deciding whether to split a domain/subdomain spec, or optimizing oversized Kontract modules
|
|
8
|
+
order: 18
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Scope, Size, and Splitting
|
|
12
|
+
|
|
13
|
+
Kontract is the next iteration of the AutoSync/AsyncAPI idea: keep the
|
|
14
|
+
documentation-first and DRY discipline, but make the boundaries more explicit.
|
|
15
|
+
Large files are not automatically bad, but they hide duplicated concepts,
|
|
16
|
+
mixed domains, and unstable generated output. Treat size limits as review
|
|
17
|
+
triggers first and hard caps second.
|
|
18
|
+
|
|
19
|
+
## Source-of-truth rule
|
|
20
|
+
|
|
21
|
+
Put durable guidance in Playbook resources and module docs; generated editor
|
|
22
|
+
rules should point back to those resources. Do not copy long rules into Cursor,
|
|
23
|
+
Claude, Codex, or generated contracts. The source contract spec and the source
|
|
24
|
+
Playbook resource are the maintained truth.
|
|
25
|
+
|
|
26
|
+
## Public example hygiene
|
|
27
|
+
|
|
28
|
+
Files under `resources/` become public AI guidance. Never use internal SUMR,
|
|
29
|
+
customer, product, infrastructure, event-subject, route, table, or data-model
|
|
30
|
+
examples there. Public examples must be sanitized and generic.
|
|
31
|
+
|
|
32
|
+
Use neutral domains such as:
|
|
33
|
+
|
|
34
|
+
- kitchen recipes and ingredients;
|
|
35
|
+
- bookstore inventory;
|
|
36
|
+
- parcel shipping;
|
|
37
|
+
- job hierarchies and departments;
|
|
38
|
+
- todos or calendar events.
|
|
39
|
+
|
|
40
|
+
Prefer `example.*`, `recipes`, `orders`, `ingredients`, `jobs`, or similarly
|
|
41
|
+
generic names. Do not use real service names, internal nouns, customer nouns,
|
|
42
|
+
NATS subject prefixes, API paths, or entity relationships as examples. Internal
|
|
43
|
+
examples are acceptable in private `docs/` only when they are necessary to
|
|
44
|
+
explain the module's current behavior.
|
|
45
|
+
|
|
46
|
+
## File size budgets
|
|
47
|
+
|
|
48
|
+
| File kind | Healthy target | Review trigger | Split/optimize trigger | Hard stop |
|
|
49
|
+
|---|---:|---:|---:|---:|
|
|
50
|
+
| Kontract TypeScript source | <= 200 lines | > 250 lines | > 400 lines | > 500 lines |
|
|
51
|
+
| OpenAPI/AsyncAPI service spec | 150-350 lines | > 400 lines | > 700 lines | > 1000 lines |
|
|
52
|
+
| Shared component YAML | 100-300 lines | > 400 lines | > 600 lines | > 900 lines |
|
|
53
|
+
| Generated TypeScript output | no manual target | review if surprising | fix generator/spec, never hand-split | no hand edits |
|
|
54
|
+
|
|
55
|
+
Exceptions require a documented reason in the PR or handoff. Generated files,
|
|
56
|
+
large fixtures, and intentionally dense compatibility snapshots are exempt from
|
|
57
|
+
manual splitting, but they can still reveal generator or spec-design problems.
|
|
58
|
+
|
|
59
|
+
## Split triggers
|
|
60
|
+
|
|
61
|
+
Split or optimize before adding more content when a file shows any of these:
|
|
62
|
+
|
|
63
|
+
- multiple product domains or subdomains in one spec;
|
|
64
|
+
- more than roughly 7-10 operations with different lifecycle owners;
|
|
65
|
+
- request/response schemas for unrelated use cases in one component block;
|
|
66
|
+
- repeated envelope, pagination, error, scalar, schedule, or config shapes;
|
|
67
|
+
- repeated operation patterns that should become shared parameters/responses;
|
|
68
|
+
- a TypeScript file with orchestration, parsing, emitting, IO, and formatting
|
|
69
|
+
responsibilities mixed together;
|
|
70
|
+
- a generated diff where a small spec change creates many near-identical files.
|
|
71
|
+
|
|
72
|
+
Do not split only by line count. First identify the product or technical
|
|
73
|
+
boundary that gives the new file a stable name and owner.
|
|
74
|
+
|
|
75
|
+
## Domain and subdomain spec structure
|
|
76
|
+
|
|
77
|
+
Use directory nesting to communicate product ownership. The path should answer
|
|
78
|
+
"who owns this contract?" and the filename should answer "which surface is this?"
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
schema/
|
|
82
|
+
shared/
|
|
83
|
+
scalars.yml
|
|
84
|
+
pagination.yml
|
|
85
|
+
errors.yml
|
|
86
|
+
events.yml
|
|
87
|
+
scheduling.yml
|
|
88
|
+
recipes/
|
|
89
|
+
recipes.openapi.yml
|
|
90
|
+
ingredients.openapi.yml
|
|
91
|
+
publishing.asyncapi.yml
|
|
92
|
+
kitchen/
|
|
93
|
+
stations.openapi.yml
|
|
94
|
+
prep-jobs.asyncapi.yml
|
|
95
|
+
inventory.asyncapi.yml
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Guidelines:
|
|
99
|
+
|
|
100
|
+
- Keep one entry-point spec per bounded API surface, not one giant file per
|
|
101
|
+
repo.
|
|
102
|
+
- Split by product meaning: `recipes`, `ingredients`, `orders`, `jobs`, or
|
|
103
|
+
`inventory`, not by generic words like `common`, `misc`, or `helpers`.
|
|
104
|
+
- Use `schema/shared/` only for cross-domain concepts with stable semantics and
|
|
105
|
+
an obvious owner.
|
|
106
|
+
- Prefer domain-local shared components when a concept is reused only inside one
|
|
107
|
+
domain.
|
|
108
|
+
- Keep `info.title` deliberate because AsyncAPI NATS namespaces derive from it;
|
|
109
|
+
filenames and titles should not drift semantically.
|
|
110
|
+
- Keep `$ref` paths repo-relative and validate after moving files.
|
|
111
|
+
|
|
112
|
+
## Refactor order for oversized specs
|
|
113
|
+
|
|
114
|
+
1. Extract repeated cross-domain scalars, pagination, errors, envelopes, events,
|
|
115
|
+
schedules, and config objects into `schema/shared/`.
|
|
116
|
+
2. Extract repeated domain-only shapes into a domain-local shared YAML file.
|
|
117
|
+
3. Split operations by subdomain when the file still mixes independently owned
|
|
118
|
+
workflows.
|
|
119
|
+
4. Validate the moved refs with `sumr kontract validate`.
|
|
120
|
+
5. Generate with the smallest useful scope and review both the spec diff and
|
|
121
|
+
generated output diff.
|
|
122
|
+
|
|
123
|
+
## Refactor order for oversized code
|
|
124
|
+
|
|
125
|
+
1. Name the current responsibilities in the file.
|
|
126
|
+
2. Extract pure helpers first, then emitters/readers, then orchestration.
|
|
127
|
+
3. Move interfaces and types into `src/types/` or `*.types.ts`; logic files
|
|
128
|
+
should import types instead of declaring them inline.
|
|
129
|
+
4. Move reusable constants to `src/lib/constants.ts` or the existing constants
|
|
130
|
+
module.
|
|
131
|
+
5. Add or adjust focused tests around the extracted seam before broad rewrites.
|
|
132
|
+
|
|
133
|
+
Prefer small safe extractions over a big rewrite. The goal is a clearer module
|
|
134
|
+
boundary, not a larger abstraction layer.
|
|
135
|
+
|
|
136
|
+
## Review checklist
|
|
137
|
+
|
|
138
|
+
Before accepting a large spec or source file:
|
|
139
|
+
|
|
140
|
+
- [ ] The file is under the healthy target, or the reason for exceeding it is
|
|
141
|
+
documented.
|
|
142
|
+
- [ ] The file has one clear product/technical owner.
|
|
143
|
+
- [ ] Shared concepts are referenced with `$ref` rather than copied.
|
|
144
|
+
- [ ] No generic bucket names (`common`, `misc`, `utils`) hide unrelated
|
|
145
|
+
responsibilities.
|
|
146
|
+
- [ ] Generated output changes match the intended API surface only.
|
|
147
|
+
- [ ] Any split keeps spec and regenerated output committed together.
|
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
base.yml ← shared components, referenced via $ref
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Rules
|
|
24
|
+
|
|
25
|
+
- OpenAPI specs end in `*.openapi.yml` / `*.openapi.yaml`.
|
|
26
|
+
- AsyncAPI specs end in `*.asyncapi.yml` / `*.asyncapi.yaml`.
|
|
27
|
+
- Discovery is recursive; `base.yml` is skipped as an entry point.
|
|
28
|
+
- Service output paths mirror nested spec paths under the configured source
|
|
29
|
+
input directory.
|
|
30
|
+
- Use nested domain/subdomain paths when one root file would mix independently
|
|
31
|
+
owned API surfaces; see the scope and splitting reference for line-count
|
|
32
|
+
thresholds and naming rules.
|
|
33
|
+
- Share common schemas through `$ref` into `base.yml`. Do **not** duplicate
|
|
34
|
+
schemas across specs and do **not** merge by hand-mutating parsed JSON.
|
|
35
|
+
- Prefer a `schema/shared/` folder for cross-domain components such as common
|
|
36
|
+
parameters, error responses, pagination, scalar constraints, response envelope
|
|
37
|
+
fragments, schedules, and reusable config objects.
|
|
38
|
+
- The NATS namespace comes from the AsyncAPI `info.title`, not the filename —
|
|
39
|
+
set `info.title` deliberately.
|
|
40
|
+
- Multi-file specs are bundled automatically (OpenAPI via Redocly core in-process
|
|
41
|
+
with CLI fallback, AsyncAPI via `@asyncapi/cli bundle`); keep `$ref` paths
|
|
42
|
+
repo-relative.
|
|
43
|
+
|
|
44
|
+
## OpenAPI authoring rules
|
|
45
|
+
|
|
46
|
+
- Put reusable HTTP payloads in `components.schemas`.
|
|
47
|
+
- Operation request/response schemas should reference components with `$ref`.
|
|
48
|
+
Inline operation schemas are rejected so generated DTO/model names stay stable.
|
|
49
|
+
- Prefer explicit object schemas over anonymous nested shapes when a payload is
|
|
50
|
+
shared by multiple operations.
|
|
51
|
+
- If multiple responses repeat the same envelope fields, extract the envelope
|
|
52
|
+
fragment and compose concrete responses with supported object `allOf`.
|
|
53
|
+
- If multiple schemas repeat the same regex or scalar validation, extract a
|
|
54
|
+
named scalar component and reference it.
|
|
55
|
+
- Use stable `operationId` values. They become Swagger metadata constants such
|
|
56
|
+
as `SWG_LIST_RECIPES`.
|
|
57
|
+
- Unsupported composition features (`oneOf`, `anyOf`, `not`, `discriminator`)
|
|
58
|
+
must either be modeled differently or implemented in Kontract before use.
|
|
59
|
+
|
|
60
|
+
## AsyncAPI operation classification
|
|
61
|
+
|
|
62
|
+
| AsyncAPI shape | Generated client kind |
|
|
63
|
+
|---------------------|-----------------------|
|
|
64
|
+
| `receive` + `reply` | Query |
|
|
65
|
+
| `receive` | Command |
|
|
66
|
+
| `send` | Event |
|
|
67
|
+
|
|
68
|
+
Run `sumr kontract validate` after any layout change to confirm specs still
|
|
69
|
+
resolve before generating.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: team-member
|
|
3
|
+
name: contract-author
|
|
4
|
+
title: Contract Author
|
|
5
|
+
description: "Owns API spec authoring and Kontract regeneration discipline: edits OpenAPI/AsyncAPI specs, validates, regenerates, and keeps generated contracts consistent without hand-editing outputs."
|
|
6
|
+
modelTier: reasoning
|
|
7
|
+
channels:
|
|
8
|
+
codex:
|
|
9
|
+
sandbox_mode: workspace-write
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Contract Author
|
|
13
|
+
|
|
14
|
+
You own the API contract source of truth for this repo. You change YAML specs
|
|
15
|
+
and let Kontract generate the TypeScript — you never hand-write or hand-patch
|
|
16
|
+
generated contracts.
|
|
17
|
+
|
|
18
|
+
Apply the generated **sumr-kontract-usage** skill, plus the configuration,
|
|
19
|
+
spec-layout, schema-reuse, scope-and-splitting, and generated-output
|
|
20
|
+
references, before acting.
|
|
21
|
+
|
|
22
|
+
## Responsibilities
|
|
23
|
+
|
|
24
|
+
- Translate API requirements into OpenAPI/AsyncAPI specs under `schema/`.
|
|
25
|
+
- After writing or updating any `*.openapi.yml` / `*.asyncapi.yml` file, review
|
|
26
|
+
it against Kontract reuse, layout, and generation rules before validating.
|
|
27
|
+
- Keep shared shapes in shared component files and reference them with `$ref`.
|
|
28
|
+
- Keep specs domain-aligned and reviewable: use domain/subdomain paths, split
|
|
29
|
+
oversized files at documented thresholds, and avoid generic `common` buckets
|
|
30
|
+
for unrelated concepts.
|
|
31
|
+
- Proactively spot duplicated envelope fields, pagination metadata, error
|
|
32
|
+
schemas, path/query params, regex scalar constraints, schedules, and config
|
|
33
|
+
objects before generating.
|
|
34
|
+
- Prefer supported object `allOf` composition when a concrete response extends
|
|
35
|
+
a shared base envelope.
|
|
36
|
+
- Run `sumr kontract validate` then `sumr kontract generate` for every change.
|
|
37
|
+
- Review the generated diff for correctness and unintended breakage.
|
|
38
|
+
- If a generated diff creates many near-identical DTO/model files, pause and
|
|
39
|
+
propose a spec-level shared component refactor.
|
|
40
|
+
- Keep spec + regenerated output committed together.
|
|
41
|
+
- When generated files are missing, check `sumr.yaml` target options and the
|
|
42
|
+
installed `SUMR Kontract module` version before changing application code.
|
|
43
|
+
|
|
44
|
+
## Boundaries
|
|
45
|
+
|
|
46
|
+
- Never edit files under the generated `contracts/` output.
|
|
47
|
+
- Never hand-write Zod schemas, DTOs, NATS subjects, or clients that Kontract owns.
|
|
48
|
+
- Do not introduce a second source of truth; the spec is authoritative.
|
|
49
|
+
- Do not over-share unrelated concepts only because their current fields look
|
|
50
|
+
similar; shared components must have the same product meaning and owner.
|
|
51
|
+
- Flag breaking contract changes for human review before commit.
|
|
52
|
+
- Scope `--clean` to the intended source/target in consumer repos.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: workflow
|
|
3
|
+
name: contract-change
|
|
4
|
+
title: Contract Change
|
|
5
|
+
description: "Guides an AI agent through safely changing an API spec and regenerating Kontract contracts."
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Contract Change
|
|
9
|
+
|
|
10
|
+
Use this workflow whenever an API surface changes (new endpoint, message,
|
|
11
|
+
field, or breaking change) and the generated contracts must follow.
|
|
12
|
+
|
|
13
|
+
## Flow
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
🕐 edit spec -> review spec -> validate -> generate -> review diff -> ⏸ HUMAN APPROVES -> commit
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Steps
|
|
20
|
+
|
|
21
|
+
1. **Edit the spec** under `schema/` (`*.openapi.yml` / `*.asyncapi.yml`).
|
|
22
|
+
Before adding new schemas, scan for existing shared components. Reuse shared
|
|
23
|
+
components via `$ref`; never duplicate schemas.
|
|
24
|
+
2. **Review the written spec** before validation. Check new or changed
|
|
25
|
+
`*.openapi.yml` / `*.asyncapi.yml` files against Kontract best practices:
|
|
26
|
+
stable component names, no inline operation payload schemas, correct `$ref`
|
|
27
|
+
paths, reusable shared components, domain/subdomain boundaries, documented
|
|
28
|
+
size thresholds, and no copy-pasted product concepts.
|
|
29
|
+
3. **Refactor repeated shapes first**. If the change repeats envelope fields,
|
|
30
|
+
pagination metadata, error bodies, ID/date params, regex scalar constraints,
|
|
31
|
+
schedules, or config objects, extract a shared component and reference it.
|
|
32
|
+
4. **Validate**: `sumr kontract validate` (scope with `--source` if large).
|
|
33
|
+
Fix every reported error before continuing.
|
|
34
|
+
5. **Generate**: `sumr kontract generate`. Unchanged specs are skipped.
|
|
35
|
+
Scope large repos with `--source`, `--target`, or `--specific`.
|
|
36
|
+
6. **Review the diff** of the generated `contracts/` output. Confirm
|
|
37
|
+
`http/models`, `http/enums`, `http/zod`, optional `http/dto`,
|
|
38
|
+
optional `http/swagger.ts`, and NATS `SUBJECTS` match the intended change;
|
|
39
|
+
watch for unintended removals. If the diff introduces many near-identical
|
|
40
|
+
generated files, return to the spec and look for a shared component.
|
|
41
|
+
7. **Do not edit generated files** to "fix" the diff — change the spec and
|
|
42
|
+
regenerate instead.
|
|
43
|
+
8. **Commit** the spec change and the regenerated output together so they
|
|
44
|
+
never drift.
|
|
45
|
+
|
|
46
|
+
## Transition rules
|
|
47
|
+
|
|
48
|
+
- Do not run `validate` or `generate` until the changed spec has been reviewed
|
|
49
|
+
for avoidable duplication and unsupported patterns.
|
|
50
|
+
- Do not run `generate` until `validate` passes clean.
|
|
51
|
+
- If the generated diff is unexpected, return to the spec — not the output.
|
|
52
|
+
- Treat a breaking contract change as requiring human approval before commit.
|
|
53
|
+
- If files that should exist are missing, compare `sumr.yaml` generator options
|
|
54
|
+
and the installed `SUMR Kontract module` version before changing application code.
|
|
55
|
+
- Use `--clean` only when you intend to remove selected generated output/cache
|
|
56
|
+
before regeneration. Prefer scoped clean commands in consumer repos:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
sumr kontract generate --source api --target backend --clean
|
|
60
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
apiVersion: sumr.dev/v1
|
|
2
|
+
kind: CliModule
|
|
3
|
+
metadata:
|
|
4
|
+
name: kontract
|
|
5
|
+
package: "@sumrco/cli"
|
|
6
|
+
description: Generate and validate API contract code
|
|
7
|
+
owners:
|
|
8
|
+
- team: "@sumr-org/kontract-team"
|
|
9
|
+
tags:
|
|
10
|
+
- contracts
|
|
11
|
+
- openapi
|
|
12
|
+
- asyncapi
|
|
13
|
+
spec:
|
|
14
|
+
visibility: public
|
|
15
|
+
group: modules
|
|
16
|
+
targets:
|
|
17
|
+
contractVersion: ^1.0.0
|
|
18
|
+
bunVersion: ">=1.1.0"
|
|
19
|
+
commands:
|
|
20
|
+
- name: init
|
|
21
|
+
summary: Activate Kontract AI guidance for this workspace
|
|
22
|
+
visibility: public
|
|
23
|
+
- name: generate
|
|
24
|
+
summary: Generate TypeScript contracts from API specs
|
|
25
|
+
visibility: public
|
|
26
|
+
- name: validate
|
|
27
|
+
summary: Validate API specifications
|
|
28
|
+
visibility: public
|
|
29
|
+
exports:
|
|
30
|
+
resources: []
|
|
31
|
+
binaries: []
|
|
32
|
+
aiResources:
|
|
33
|
+
module: kontract
|
|
34
|
+
roots:
|
|
35
|
+
- ./resources
|
|
36
|
+
activation:
|
|
37
|
+
mode: command
|
|
38
|
+
initCommand: kontract init
|
|
39
|
+
key: kontract
|
|
40
|
+
flags:
|
|
41
|
+
experimental: false
|
|
42
|
+
deprecated: null
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flow-actions
|
|
3
|
+
title: Mission Flow Actions
|
|
4
|
+
description: "Canonical Mission action IDs and what each action means."
|
|
5
|
+
label: Flow Actions
|
|
6
|
+
when: Mapping Mission next actions to commands, reports, PR previews, or closeout
|
|
7
|
+
order: 20
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Mission Flow Actions
|
|
11
|
+
|
|
12
|
+
Known action IDs:
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
issue.sync
|
|
16
|
+
context.research
|
|
17
|
+
plan.create
|
|
18
|
+
plan.approve
|
|
19
|
+
branch.check
|
|
20
|
+
work.claim
|
|
21
|
+
implementation.report
|
|
22
|
+
review.report
|
|
23
|
+
validation.report
|
|
24
|
+
quality.gate
|
|
25
|
+
pr.prepare
|
|
26
|
+
pr.create
|
|
27
|
+
mission.close
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`issue.sync` is not only identifier normalization. For tracker-backed work it
|
|
31
|
+
requires reading the work item title, description/body, acceptance criteria,
|
|
32
|
+
todos/checklists, linked docs, comments/discussion, and attachments or embedded
|
|
33
|
+
images/screenshots. Comments are part of the source of truth because they often
|
|
34
|
+
contain decisions, updated errors, blockers, and scope changes.
|
|
35
|
+
|
|
36
|
+
`branch.check` must confirm the implementation branch before claim or PR work. Use any stored Mission branch or claim branch as the default branch. If the current checkout differs, switch to the stored branch or ask before intentionally reclaiming the Mission. Check local and remote branches and open PRs for the issue key when those tools are available.
|
|
37
|
+
|
|
38
|
+
Do not skip directly to implementation when `plan.approve` is pending. Do not create a PR when validation or quality evidence is missing unless the user explicitly asks for a draft or preview.
|
|
39
|
+
|
|
40
|
+
Use `sumr mission next` as the source of truth for the next action.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flow-config
|
|
3
|
+
title: Mission Flow Config
|
|
4
|
+
description: "How Mission reads sumr.yaml flow config, presets, step order, and transition policies."
|
|
5
|
+
label: Flow Config
|
|
6
|
+
when: Reading, changing, or explaining Mission flow behavior
|
|
7
|
+
order: 10
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Mission Flow Config
|
|
11
|
+
|
|
12
|
+
Mission flow is repo configuration in `sumr.yaml`; runtime state stays in `.sumr-cache/mission`.
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
mission:
|
|
16
|
+
tracker:
|
|
17
|
+
provider: github
|
|
18
|
+
git:
|
|
19
|
+
provider: github
|
|
20
|
+
prMode: ask
|
|
21
|
+
flow:
|
|
22
|
+
preset: standard-delivery
|
|
23
|
+
steps:
|
|
24
|
+
- uses: plan.create
|
|
25
|
+
advance: auto
|
|
26
|
+
- uses: plan.approve
|
|
27
|
+
advance: human
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Use only known action IDs. Do not invent actions, shell commands, graph edges, or tracker mutations.
|
|
31
|
+
|
|
32
|
+
Transition policies:
|
|
33
|
+
|
|
34
|
+
- `auto`: continue when the action is already satisfied.
|
|
35
|
+
- `ask`: ask before continuing.
|
|
36
|
+
- `human`: stop until explicit human approval.
|
|
37
|
+
- `manual`: wait for a command, report, or user action to satisfy the step.
|
|
38
|
+
|
|
39
|
+
When a mission starts, the active flow is snapshotted into mission state. Later YAML edits should not silently rewrite older missions.
|