macca-method 1.0.0 → 2.0.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.
Files changed (56) hide show
  1. package/.agents/legacy-payloads.json +22 -0
  2. package/{skills-lock.json → .agents/macca-lock.json} +4 -2
  3. package/.agents/macca-managed-skills.txt +4 -2
  4. package/.agents/skills/_shared/references/additional-skills.md +30 -0
  5. package/.agents/skills/_shared/references/brainstorm-session.md +42 -11
  6. package/.agents/skills/_shared/references/config-mutation.md +25 -0
  7. package/.agents/skills/_shared/references/finding-format.md +25 -0
  8. package/.agents/skills/_shared/references/fix-mode.md +39 -0
  9. package/.agents/skills/_shared/references/human-loop.md +3 -1
  10. package/.agents/skills/_shared/references/implementation-principles.md +19 -0
  11. package/.agents/skills/_shared/references/invocation-policy.md +39 -0
  12. package/.agents/skills/_shared/references/language-config.md +15 -0
  13. package/.agents/skills/_shared/references/output-ownership.md +4 -2
  14. package/.agents/skills/_shared/references/runtime-config.md +7 -168
  15. package/.agents/skills/_shared/references/skill-catalog.md +34 -0
  16. package/.agents/skills/_shared/scripts/validate-skills.py +106 -4
  17. package/.agents/skills/add-feature/SKILL.md +10 -7
  18. package/.agents/skills/brainstorm-api/SKILL.md +49 -194
  19. package/.agents/skills/brainstorm-api/assets/api.template.md +147 -0
  20. package/.agents/skills/brainstorm-architecture/SKILL.md +22 -127
  21. package/.agents/skills/brainstorm-architecture/assets/architecture.template.md +135 -0
  22. package/.agents/skills/brainstorm-prd/SKILL.md +19 -102
  23. package/.agents/skills/brainstorm-prd/assets/PRD.template.md +106 -0
  24. package/.agents/skills/brainstorm-rules/SKILL.md +17 -151
  25. package/.agents/skills/brainstorm-rules/assets/rules.template.md +127 -0
  26. package/.agents/skills/brainstorm-schema/SKILL.md +49 -115
  27. package/.agents/skills/brainstorm-schema/assets/schema.template.md +109 -0
  28. package/.agents/skills/brainstorm-styleguide/SKILL.md +19 -134
  29. package/.agents/skills/brainstorm-styleguide/assets/StyleGuide.template.md +147 -0
  30. package/.agents/skills/brainstorm-task/SKILL.md +22 -107
  31. package/.agents/skills/brainstorm-task/assets/Task.template.md +113 -0
  32. package/.agents/skills/bug-fix/SKILL.md +45 -54
  33. package/.agents/skills/code-review/SKILL.md +26 -19
  34. package/.agents/skills/code-review/references/review-checklist.md +24 -26
  35. package/.agents/skills/developer/SKILL.md +25 -39
  36. package/.agents/skills/developer/references/close-phase.md +25 -0
  37. package/.agents/skills/developer/references/execute-task.md +69 -0
  38. package/.agents/skills/developer/references/onboarding.md +47 -0
  39. package/.agents/skills/help/SKILL.md +12 -13
  40. package/.agents/skills/meet/SKILL.md +168 -0
  41. package/.agents/skills/quick-dev/SKILL.md +209 -0
  42. package/.agents/skills/release-readiness/SKILL.md +149 -0
  43. package/.agents/skills/spec-audit/SKILL.md +37 -22
  44. package/.agents/skills/spec-compliance/SKILL.md +41 -40
  45. package/.agents/skills/spec-init/SKILL.md +29 -14
  46. package/README.md +253 -170
  47. package/bin/macca-method.js +785 -91
  48. package/flow.webp +0 -0
  49. package/image-macca-method.webp +0 -0
  50. package/package.json +13 -6
  51. package/scripts/run-skill-validator.js +24 -0
  52. package/scripts/test-install.js +398 -0
  53. package/scripts/test-upgrade-legacy.js +107 -0
  54. package/scripts/validate-skill-behavior.js +124 -0
  55. package/.agents/skills/developer/references/execution-workflow.md +0 -322
  56. package/.agents/skills/rapat/SKILL.md +0 -172
@@ -7,8 +7,17 @@ import sys
7
7
  from pathlib import Path
8
8
 
9
9
 
10
- ROOT = Path(__file__).resolve().parents[4]
11
- SKILLS_DIR = ROOT / ".agents" / "skills"
10
+ SKILLS_DIR = Path(__file__).resolve().parents[2]
11
+ ALLOWED_FRONTMATTER = {
12
+ "name",
13
+ "description",
14
+ "license",
15
+ "compatibility",
16
+ "metadata",
17
+ "allowed-tools",
18
+ }
19
+ NAME_RE = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
20
+ MARKDOWN_LINK_RE = re.compile(r"\[[^\]]*\]\(([^)]+)\)")
12
21
 
13
22
 
14
23
  def read(path: Path) -> str:
@@ -19,11 +28,93 @@ def has_toc(text: str) -> bool:
19
28
  return "## Daftar Isi" in text or "## Table of Contents" in text
20
29
 
21
30
 
31
+ def parse_frontmatter(path: Path, text: str) -> tuple[dict[str, object], list[str]]:
32
+ issues: list[str] = []
33
+ lines = text.splitlines()
34
+ if not lines or lines[0] != "---":
35
+ return {}, [f"{path}: SKILL.md must start with YAML frontmatter on line 1"]
36
+
37
+ try:
38
+ end = lines.index("---", 1)
39
+ except ValueError:
40
+ return {}, [f"{path}: frontmatter closing delimiter is missing"]
41
+
42
+ data: dict[str, object] = {}
43
+ current_map: str | None = None
44
+ for line_number, line in enumerate(lines[1:end], start=2):
45
+ if not line.strip() or line.lstrip().startswith("#"):
46
+ continue
47
+ if line.startswith(" "):
48
+ if current_map != "metadata" or ":" not in line:
49
+ issues.append(f"{path}:{line_number}: unsupported nested frontmatter value")
50
+ continue
51
+ key, value = line.strip().split(":", 1)
52
+ metadata = data.setdefault("metadata", {})
53
+ assert isinstance(metadata, dict)
54
+ metadata[key] = value.strip().strip('"\'')
55
+ continue
56
+ if ":" not in line:
57
+ issues.append(f"{path}:{line_number}: invalid frontmatter line")
58
+ continue
59
+ key, value = line.split(":", 1)
60
+ key = key.strip()
61
+ if key in data:
62
+ issues.append(f"{path}:{line_number}: duplicate frontmatter key {key}")
63
+ value = value.strip()
64
+ if value:
65
+ data[key] = value.strip('"\'')
66
+ current_map = None
67
+ else:
68
+ data[key] = {}
69
+ current_map = key
70
+
71
+ return data, issues
72
+
73
+
74
+ def check_local_links(path: Path, text: str) -> list[str]:
75
+ issues: list[str] = []
76
+ for raw_target in MARKDOWN_LINK_RE.findall(text):
77
+ target = raw_target.split("#", 1)[0].strip()
78
+ if not target or "://" in target or target.startswith("#"):
79
+ continue
80
+ resolved = (path.parent / target).resolve()
81
+ if not resolved.exists():
82
+ issues.append(f"{path}: broken local link {raw_target}")
83
+ return issues
84
+
85
+
22
86
  def check_skill_file(path: Path) -> list[str]:
23
87
  issues: list[str] = []
24
88
  text = read(path)
25
89
  lines = text.splitlines()
26
90
 
91
+ frontmatter, frontmatter_issues = parse_frontmatter(path, text)
92
+ issues.extend(frontmatter_issues)
93
+ if frontmatter:
94
+ unknown = sorted(set(frontmatter) - ALLOWED_FRONTMATTER)
95
+ if unknown:
96
+ issues.append(f"{path}: unsupported frontmatter fields: {', '.join(unknown)}")
97
+
98
+ name = frontmatter.get("name")
99
+ description = frontmatter.get("description")
100
+ if not isinstance(name, str) or not NAME_RE.fullmatch(name) or len(name) > 64:
101
+ issues.append(f"{path}: invalid skill name {name!r}")
102
+ elif name != path.parent.name:
103
+ issues.append(f"{path}: name {name!r} does not match folder {path.parent.name!r}")
104
+ if not isinstance(description, str) or not description or len(description) > 1024:
105
+ issues.append(f"{path}: description must contain 1-1024 characters")
106
+ metadata = frontmatter.get("metadata")
107
+ if metadata is not None and (
108
+ not isinstance(metadata, dict)
109
+ or any(not isinstance(key, str) or not isinstance(value, str) for key, value in metadata.items())
110
+ ):
111
+ issues.append(f"{path}: metadata must be a string-to-string map")
112
+ compatibility = frontmatter.get("compatibility")
113
+ if compatibility is not None and (
114
+ not isinstance(compatibility, str) or not 1 <= len(compatibility) <= 500
115
+ ):
116
+ issues.append(f"{path}: compatibility must contain 1-500 characters")
117
+
27
118
  if len(lines) > 500:
28
119
  issues.append(f"{path}: more than 500 lines ({len(lines)})")
29
120
 
@@ -37,6 +128,11 @@ def check_skill_file(path: Path) -> list[str]:
37
128
  f"{path}: possible broken nested fence; check and use 4 backticks for the outer template"
38
129
  )
39
130
 
131
+ if "[GATE — Fix mode: report-first]" in text and "Approval Resume Protocol" not in text:
132
+ issues.append(f"{path}: report-first gate has no approval resume protocol")
133
+
134
+ issues.extend(check_local_links(path, text))
135
+
40
136
  return issues
41
137
 
42
138
 
@@ -56,16 +152,22 @@ def check_reference_file(path: Path) -> list[str]:
56
152
  f"{path}: chained reference to runtime-config; caller skill should read shared refs directly"
57
153
  )
58
154
 
155
+ issues.extend(check_local_links(path, text))
156
+
59
157
  return issues
60
158
 
61
159
 
62
160
  def main() -> int:
63
161
  issues: list[str] = []
162
+ skill_files = sorted(SKILLS_DIR.glob("**/SKILL.md"))
163
+ if not skill_files:
164
+ print(f"Skill validator findings:\n- {SKILLS_DIR}: no SKILL.md files found")
165
+ return 1
64
166
 
65
- for skill_md in SKILLS_DIR.glob("**/SKILL.md"):
167
+ for skill_md in skill_files:
66
168
  issues.extend(check_skill_file(skill_md))
67
169
 
68
- for ref in SKILLS_DIR.glob("**/references/*.md"):
170
+ for ref in sorted(SKILLS_DIR.glob("**/references/*.md")):
69
171
  issues.extend(check_reference_file(ref))
70
172
 
71
173
  if not issues:
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  name: add-feature
3
- description: Skill for adding new features to running projects. Read current specs, identify all affected documents, update every impacted spec, then add a phase and tasks to Task.md.
4
- persona: "Galbi"
5
- persona_role: "Project Manager"
3
+ description: Adds an approved new feature to a running project by updating every affected spec and delegating a new Task.md phase. Use only when the user explicitly asks to expand official product or business scope.
4
+ compatibility: Requires the complete MACCA-METHOD collection with sibling _shared resources and workspace file access.
5
+ metadata:
6
+ persona: "Galbi"
7
+ persona-role: "Project Manager"
6
8
  ---
7
9
 
8
10
  # Add Feature
@@ -11,9 +13,10 @@ persona_role: "Project Manager"
11
13
 
12
14
  At startup:
13
15
 
14
- 1. Read `../_shared/references/runtime-config.md`.
16
+ 1. Read `../_shared/references/language-config.md`.
15
17
  2. Read `../_shared/references/output-ownership.md`.
16
- 3. Use `languagePreferences.communication.normalized` for feature analysis and reports.
18
+ 3. Read `../_shared/references/scope-rules.md`.
19
+ 4. Use `languagePreferences.communication.normalized` for feature analysis and reports.
17
20
 
18
21
  ---
19
22
 
@@ -114,7 +117,7 @@ For each **IMPACTED** document, update it in this order:
114
117
  7. `project-context/plans/` — if a plan file exists for the affected phase (for example `plans/phase-2-checkout.md`), update it to reflect the new scope. Add a section: `## Feature Addition: [feature name]` with a short description of the approach change. Do not overwrite existing plan content.
115
118
 
116
119
  ### Update Principles:
117
- - **Add, do not overwrite** — append to the relevant section; do not change existing content unless there is a conflict
120
+ - **Preserve unrelated content and IDs** — make the smallest targeted edit needed to keep each affected document internally consistent; update an existing statement when the approved feature changes it
118
121
  - **Match the existing style** — follow the current document format and tone
119
122
  - **Make additions clear** — place them logically; no special tags are needed
120
123
  - **Preserve old IDs** — assign new IDs for new items using the existing pattern
@@ -185,6 +188,6 @@ To start building, call `developer`.
185
188
  1. **Read all specs before impact analysis** — no assumptions
186
189
  2. **Every impacted spec MUST be updated** — no exceptions
187
190
  3. **Get user approval after impact analysis** — before making changes
188
- 4. **Only add** — do not overwrite unless there is a real conflict
191
+ 4. **Preserve unrelated content** — update stale affected statements instead of appending contradictions
189
192
  5. **Update Task.md last** — via `brainstorm-task` after all specs are done
190
193
  6. **Acceptance criteria must be testable** — not vague descriptions
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  name: brainstorm-api
3
- description: Interview users and generate `api.md` (Endpoint Documentation / API Contract). Use after `schema.md` is complete to document all API endpoints.
4
- persona: "Fachri"
5
- persona_role: "Tech Lead"
3
+ description: Interviews users and generates `api.md` for REST, GraphQL, RPC/tRPC, event-driven, or mixed contracts, including lifecycle and reliability. Use only when the user explicitly requests an API contract after applicable architecture/data decisions.
4
+ compatibility: Requires the complete MACCA-METHOD collection with sibling _shared resources and workspace file access.
5
+ metadata:
6
+ persona: "Fachri"
7
+ persona-role: "Tech Lead"
6
8
  ---
7
9
 
8
10
  # Brainstorm API
@@ -34,12 +36,13 @@ You are **@Fachri — Tech Lead**, a **Senior API Architect** who designs clear,
34
36
 
35
37
  Before any interview:
36
38
 
37
- 1. Read `../_shared/references/runtime-config.md`.
38
- 2. Read `../_shared/references/brainstorm-session.md`.
39
- 3. Read `../_shared/references/scope-rules.md`.
39
+ 1. Read `../_shared/references/language-config.md`.
40
+ 2. Read `../_shared/references/config-mutation.md`.
41
+ 3. Read `../_shared/references/brainstorm-session.md`.
42
+ 4. Read `../_shared/references/scope-rules.md`.
40
43
  4. Use `languagePreferences.communication.normalized` for chat.
41
44
  5. Use `languagePreferences.documents.normalized` for the final `project-context/api.md`.
42
- 6. Apply `brainstormPreferences.discussionMode` and `brainstormPreferences.recommendations` using the shared session policy.
45
+ 6. Apply `brainstormPreferences.discussionMode`, `recommendations`, and `discoveryDepth` using the shared session policy.
43
46
 
44
47
  ---
45
48
 
@@ -63,7 +66,7 @@ Before any interview:
63
66
  - **provider contract mode** → document endpoints as backend implementation contracts, including relevant data/auth/service dependencies.
64
67
  - **full contract mode** → combine consumer + provider views as the project requires.
65
68
 
66
- 5. Run the shared runtime setup above. For this skill, ask whether to cover the 5 global topics one by one or three at once, then apply the stored or chosen recommendation preference.
69
+ 5. Run the shared runtime setup above and apply all three pacing modes from the shared session policy. If preferences are saved, announce and proceed without another confirmation.
67
70
 
68
71
  6. Run the interview in the chosen mode. Wait for answers.
69
72
 
@@ -75,22 +78,30 @@ Before any interview:
75
78
 
76
79
  ## Interview Topics (5 Topics)
77
80
 
78
- Ask all five topics. Wait for the answer before moving on.
81
+ Ask all five topics using the selected batch size. First determine the API style from `architecture.md`: REST, GraphQL, tRPC/RPC, event-driven, or mixed. Use protocol-neutral terms until that choice is known.
79
82
 
80
- ### 1. Base URL, Versioning, Auth & Contract Status
81
- *"What is the base URL? Is versioning in the URL? How do users authenticate? Is the contract confirmed, proposed, or mock-only?"*
83
+ Protocol mapping:
84
+ - REST: method, path, HTTP status, body/query/path parameters
85
+ - GraphQL: operation type/name, arguments, selection/result type, errors
86
+ - tRPC/RPC: procedure name/type, input/output schema, typed errors
87
+ - Event-driven: channel/topic, producer/consumer, payload schema, delivery/idempotency rules
88
+ - Mixed: separate sections per protocol; do not force one protocol's fields onto another
89
+
90
+ ### 1. Entry Point, Versioning, Auth & Contract Status
91
+ *"What is the API entry point and protocol? How is compatibility/versioning handled? How do users authenticate? Is the contract confirmed, proposed, or mock-only?"*
82
92
 
83
93
  Collect:
84
- - Base URL (dev: `http://localhost:3000/api/v1`, prod: `https://api.domain.com/v1`)
85
- - Versioning strategy (URI path `/v1/` or header `api-version`)
86
- - Auth header (Bearer token, Cookie, API Key)
94
+ - Entry point appropriate to the selected protocol (base URL, GraphQL endpoint, RPC router, channel/broker)
95
+ - Compatibility/versioning strategy appropriate to the protocol
96
+ - Deprecation policy for external consumers: support window, notice channel, replacement operation, and sunset criteria
97
+ - Authentication/identity transport appropriate to the protocol
87
98
  - Does cookie/session auth need CSRF protection?
88
99
  - Token lifetime, refresh, rotation, logout behavior
89
100
  - Standard response wrapper format (for example `{ success, data, message, meta }`)
90
101
  - Contract status by area: `confirmed`, `proposed`, `mock-only`, `backend-owned`, `pending backend confirmation`
91
102
 
92
103
  ### 2. Error Catalog
93
- *"What is the error response format? Which HTTP status codes are used?"*
104
+ *"What is the error format for the selected protocol? For REST, which HTTP status codes are used; for typed protocols, which error codes/types are exposed?"*
94
105
 
95
106
  Collect:
96
107
  - Consistent error response structure
@@ -104,197 +115,41 @@ Collect:
104
115
  - `429` Too Many Requests — rate limit reached
105
116
  - `500` Internal Server Error
106
117
  - Application-level error codes in the response body? (for example `{ "code": "USER_NOT_FOUND" }`)
118
+ - Retry classification: retryable or terminal, client action, timeout interaction, backoff, and `Retry-After`/protocol equivalent
107
119
 
108
- ### 3. Endpoint List by Resource
109
- *"What endpoints are needed? List them by resource or module."*
120
+ ### 3. Operation List by Resource
121
+ *"What operations are needed? List endpoints, queries/mutations, procedures, or events by resource/module."*
110
122
 
111
123
  Collect per resource:
112
- - Are standard CRUD endpoints needed? `GET /` (list), `GET /:id`, `POST /`, `PUT /:id`, `PATCH /:id`, `DELETE /:id`
113
- - Custom non-CRUD endpoints (for example `POST /auth/login`, `POST /orders/:id/cancel`)
114
- - Which endpoints require authentication?
115
- - Authorization/ownership rules per endpoint?
124
+ - Which protocol-native operations are needed: REST actions, GraphQL queries/mutations/subscriptions, RPC procedures, or produced/consumed events?
125
+ - Which operations require authentication?
126
+ - Authorization/ownership rules per operation?
116
127
 
117
128
  ### 4. Request & Response Details
118
- *"For each endpoint, what data is sent and returned? Include real examples."*
129
+ *"For each operation, what input is accepted and what result or event is produced? Include protocol-native examples."*
119
130
 
120
- Collect per endpoint:
121
- - **Request:** JSON body, path params (`:id`), query params (`?page=1&limit=20`)
122
- - **Success Response:** Schema + real JSON example
123
- - **Error Response:** Schema for each relevant error code
124
- - Field constraints (required/optional, type, validation)
125
- - Security notes: CSRF, idempotency, signed webhooks, upload limits, ownership checks
131
+ Collect by selected protocol:
132
+ - **REST:** method/path, body/path/query/header inputs, success/error response and status
133
+ - **GraphQL:** operation name/type, arguments, selection/result type, union/error behavior
134
+ - **RPC/tRPC:** procedure type/name, typed input/output, typed errors
135
+ - **Event-driven:** channel/topic, producer/consumer, payload, key/order, delivery and retry semantics
136
+ - **All modes:** field constraints, authorization/ownership, idempotency/replay, upload/payload limits, and real examples
126
137
 
127
138
  ### 5. Pagination, Filtering, Rate Limiting & Abuse Protection
128
- *"For list endpoints, how do pagination and filtering work? How are sensitive endpoints protected?"*
129
-
130
- Collect:
131
- - **Pagination:** Offset-based (`?page=1&limit=20`) or cursor-based (`?after=cursor_id`)?
132
- - **Response envelope:** How are list data + metadata structured? (`total`, `page`, `hasNext`, etc.)
133
- - **Filtering:** Query params for filtering (for example `?status=active&category=books`)
134
- - **Sorting:** `?sort=created_at&order=desc`
135
- - **Rate Limiting:** Limit per minute/hour? Response headers?
136
- - **Sensitive endpoints:** Which need extra protection (login, password reset, upload, webhook, payment)?
137
- - **Idempotency/Replay Protection:** Which endpoints need it?
138
-
139
- ## api.md Output Format
140
-
141
- ````markdown
142
- # API Documentation
143
-
144
- ## Document Role
145
- - **Source of Truth:** External API contract for this project
146
- - **Primary Owner:** `brainstorm-api`
147
- - **Out of Scope:** Internal service architecture, DB migration details, and UI copy
148
-
149
- ## Scope Summary
150
- | Area | Status | Notes |
151
- |------|--------|-------|
152
- | [resource / module] | Covered / Planned / Deferred | [short note] |
153
-
154
- ## Canonical Terminology
155
- | Term | Meaning |
156
- |------|---------|
157
- | [term] | [exact meaning used in this API contract] |
158
-
159
- ## Environments
160
- | Environment | Base URL |
161
- |-------------|----------|
162
- | Development | `http://localhost:3000/api/v1` |
163
- | Staging | `https://staging-api.domain.com/v1` |
164
- | Production | `https://api.domain.com/v1` |
165
-
166
- ## Versioning
167
- - **Strategy:** URI path `/v1/` / Header `api-version: 1`
168
- - **Current Version:** v1
169
-
170
- ## Authentication
171
- - **Method:** Bearer Token (JWT)
172
- - **Header:** `Authorization: Bearer <token>`
173
- - **Login Endpoint:** `POST /auth/login`
174
- - **Refresh Endpoint:** `POST /auth/refresh`
175
-
176
- ## Security Controls
177
- - **CSRF Protection:** Yes / No / Not applicable — [when it applies]
178
- - **Ownership/Authorization Rules:** [access control summary]
179
- - **Sensitive Endpoints:** [login / password reset / upload / webhook / payment / admin actions]
180
- - **Idempotency/Replay Protection:** [which endpoints need it and how]
181
- - **Webhook Verification/Signing:** [if external integrations exist]
182
-
183
- ## Standard Response Format
184
- ```json
185
- {
186
- "success": true,
187
- "data": {},
188
- "message": "string (optional)",
189
- "meta": {
190
- "page": 1,
191
- "limit": 20,
192
- "total": 100,
193
- "hasNext": true
194
- }
195
- }
196
- ```
197
-
198
- ## Error Catalog
199
- | HTTP Code | Internal Code | Meaning |
200
- |-----------|---------------|---------|
201
- | 400 | `VALIDATION_ERROR` | Invalid input; details in the `errors` field |
202
- | 401 | `UNAUTHORIZED` | Missing or expired token |
203
- | 403 | `FORBIDDEN` | No permission for this resource |
204
- | 404 | `NOT_FOUND` | Resource does not exist |
205
- | 409 | `CONFLICT` | Duplicate data (for example email already registered) |
206
- | 422 | `UNPROCESSABLE` | Business logic validation failed |
207
- | 429 | `RATE_LIMIT` | Too many requests; check the `Retry-After` header |
208
- | 500 | `SERVER_ERROR` | Internal server error |
209
-
210
- **Error Response Format:**
211
- ```json
212
- {
213
- "success": false,
214
- "message": "User-friendly error message",
215
- "code": "INTERNAL_CODE",
216
- "errors": [
217
- { "field": "email", "message": "Invalid email format" }
218
- ]
219
- }
220
- ```
221
-
222
- ## Pagination
223
- - **Type:** Offset-based / Cursor-based
224
- - **Default:** `limit=20`, `page=1`
225
- - **Max Limit:** `100`
226
-
227
- ## Rate Limiting
228
- - **Limit:** [X requests per minute]
229
- - **Headers:** `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`
230
-
231
- ## Endpoint Inventory
232
- | ID | Method | Path | Auth | Trace to |
233
- |----|--------|------|------|----------|
234
- | API-01 | GET | `/[resource]` | Required / Public | `FEAT-01` |
235
- | API-02 | POST | `/[resource]` | Required | `FEAT-01` |
139
+ *"How do collection/stream access, flow control, and abuse protection work for the selected protocol?"*
236
140
 
237
- ---
238
-
239
- ## Resource: [Resource Name]
240
- **Trace to:** [FEAT-01 / AC-01]
241
-
242
- ### API-01 GET /[resource]
243
- **Description:** Get a list of [resource]
244
- **Auth:** Required / Public
245
- **Authorization:** [role / ownership rule]
246
-
247
- **Query Params:**
248
- | Param | Type | Default | Description |
249
- |-------|------|---------|-------------|
250
- | page | number | 1 | Page number |
251
- | limit | number | 20 | Items per page |
252
- | [filter] | string | - | Filter by [field] |
253
-
254
- **200 Response:**
255
- ```json
256
- {
257
- "success": true,
258
- "data": [{ "id": "uuid", "...": "..." }],
259
- "meta": { "page": 1, "limit": 20, "total": 100, "hasNext": true }
260
- }
261
- ```
262
-
263
- ---
141
+ Collect by selected protocol:
142
+ - **REST/GraphQL/RPC:** cursor/offset pagination where applicable, filtering, sorting, query complexity/depth, batching, and rate/concurrency limits
143
+ - **Event-driven:** partition/key strategy, ordering, backpressure, delivery guarantee, retry/dead-letter policy, deduplication, and consumer limits
144
+ - **All modes:** sensitive operations, quotas, idempotency/replay protection, and how clients observe limit errors
145
+ - API-specific SLOs inherited from PRD NFRs: latency, availability, timeout, and error target where relevant
146
+ - Contract-test invariants/examples required to verify consumer/provider compatibility
264
147
 
265
- ### API-02 — POST /[resource]
266
- **Description:** Create a new [resource]
267
- **Auth:** Required
268
- **Authorization:** [role / ownership rule]
269
-
270
- **Request Body:**
271
- ```json
272
- {
273
- "field": "string | required",
274
- "field2": "number | optional"
275
- }
276
- ```
277
-
278
- **201 Response:**
279
- ```json
280
- {
281
- "success": true,
282
- "data": { "id": "uuid", "...": "..." }
283
- }
284
- ```
285
-
286
- **Possible Errors:** `400` (validation), `409` (duplicate), `401` (not logged in)
287
-
288
- **Security Notes:** [CSRF / idempotency / upload limits / ownership checks / none]
289
-
290
- ---
148
+ ## api.md Output
291
149
 
292
- *[Repeat for each endpoint]*
150
+ After discovery is complete and immediately before generating `project-context/api.md`, read `assets/api.template.md`.
293
151
 
294
- ## Assumptions & Open Questions
295
- - [Unresolved API assumption or question]
296
- - [Decision still pending confirmation]
297
- ````
152
+ Adapt only sections that are applicable and preserve every required contract from the interview. Do not load the template during early discovery.
298
153
 
299
154
  ## After api.md Is Created
300
155
 
@@ -0,0 +1,147 @@
1
+ # API Documentation
2
+
3
+ ## Document Role
4
+ - **Source of Truth:** External API or integration contract for this project
5
+ - **Primary Owner:** `brainstorm-api`
6
+ - **Out of Scope:** Internal service architecture, DB migration details, and UI copy
7
+
8
+ ## Scope Summary
9
+ | Area | Status | Notes |
10
+ |------|--------|-------|
11
+ | [resource / module] | Covered / Planned / Deferred | [short note] |
12
+
13
+ ## Canonical Terminology
14
+ | Term | Meaning |
15
+ |------|---------|
16
+ | [term] | [exact meaning used in this API contract] |
17
+
18
+ ## Protocol Profile
19
+ - **Style:** REST / GraphQL / RPC-tRPC / Event-driven / Mixed
20
+ - **Entry Point:** [base URL / endpoint / router / broker/topic namespace]
21
+ - **Versioning:** [strategy and current version]
22
+ - **Deprecation:** [notice channel, support window, replacement, sunset criteria]
23
+
24
+ ## Authentication and Security Controls
25
+ - **Authentication:** [method and transport]
26
+ - **Authorization:** [role/ownership summary]
27
+ - **Sensitive Operations:** [login / password reset / upload / webhook / payment / admin actions]
28
+ - **CSRF / Replay / Signature / Idempotency:** [applicable controls]
29
+ - **Rate / Concurrency Limits:** [limit and client-visible signals]
30
+
31
+ ## Error Catalog
32
+ | Protocol Code | Internal Code | Meaning | Retryable | Client Action |
33
+ |---------------|---------------|---------|-----------|---------------|
34
+ | [400 / UNAUTHENTICATED / EVENT_RETRY / etc.] | `[CODE]` | [meaning] | Yes / No | [action] |
35
+
36
+ ## Reliability and SLO
37
+ - **Latency Target:** [p95/p99 or N/A]
38
+ - **Availability/Error Target:** [target or inherited NFR]
39
+ - **Timeout Ownership:** [client/server/gateway/consumer]
40
+ - **Retry Policy:** [which failures, backoff, max attempts]
41
+ - **Contract Test Invariants:** [critical examples/compatibility rules]
42
+
43
+ ## Operation Inventory
44
+ | ID | Operation Type | Name / Path / Topic | Auth | Trace to |
45
+ |----|----------------|---------------------|------|----------|
46
+ | API-01 | [REST GET / GraphQL query / RPC procedure / Event publish] | [identifier] | Required / Public | `FEAT-01` |
47
+
48
+ ---
49
+
50
+ ## REST Section (include only for REST or Mixed)
51
+
52
+ ### Environments
53
+ | Environment | Base URL |
54
+ |-------------|----------|
55
+ | Development | `http://localhost:3000/api/v1` |
56
+ | Staging | `https://staging-api.domain.com/v1` |
57
+ | Production | `https://api.domain.com/v1` |
58
+
59
+ ### Standard Response Format
60
+ ```json
61
+ {
62
+ "success": true,
63
+ "data": {},
64
+ "message": "string (optional)",
65
+ "meta": {
66
+ "page": 1,
67
+ "limit": 20,
68
+ "total": 100,
69
+ "hasNext": true
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### Pagination and Filtering
75
+ - **Type:** Offset-based / Cursor-based
76
+ - **Defaults:** [limit/page or cursor rules]
77
+ - **Sorting/Filtering:** [query parameters]
78
+
79
+ ### Resource: [Resource Name]
80
+ **Trace to:** [FEAT-01 / AC-01]
81
+
82
+ #### API-01 — [METHOD] /[path]
83
+ - **Description:** [what it does]
84
+ - **Auth:** [Required / Public]
85
+ - **Authorization:** [rule]
86
+ - **Input:** [body/path/query/header fields]
87
+ - **Success Response:** [example]
88
+ - **Possible Errors:** [codes]
89
+ - **Security Notes:** [CSRF / idempotency / upload / ownership]
90
+
91
+ ---
92
+
93
+ ## GraphQL Section (include only for GraphQL or Mixed)
94
+
95
+ ### Endpoint and Transport
96
+ - **Endpoint:** `/graphql`
97
+ - **Realtime:** Subscriptions / polling / none
98
+
99
+ ### Operation: [Query / Mutation / Subscription Name]
100
+ **Trace to:** [FEAT-01 / AC-01]
101
+
102
+ - **Type:** Query / Mutation / Subscription
103
+ - **Arguments:** [typed input]
104
+ - **Selection/Result Shape:** [expected result]
105
+ - **Auth & Authorization:** [rules]
106
+ - **Errors:** [codes/unions/extensions]
107
+ - **Complexity / Depth / Pagination:** [rules]
108
+
109
+ ---
110
+
111
+ ## RPC / tRPC Section (include only for RPC or Mixed)
112
+
113
+ ### Router / Namespace
114
+ - **Entry Point:** [router/namespace]
115
+
116
+ ### Procedure: [Name]
117
+ **Trace to:** [FEAT-01 / AC-01]
118
+
119
+ - **Type:** Query / Mutation / Subscription / Procedure
120
+ - **Input Schema:** [typed input]
121
+ - **Output Schema:** [typed output]
122
+ - **Auth & Authorization:** [rules]
123
+ - **Typed Errors:** [codes/types]
124
+ - **Retry / Idempotency:** [rules]
125
+
126
+ ---
127
+
128
+ ## Event-Driven Section (include only for Event-driven or Mixed)
129
+
130
+ ### Channel Topology
131
+ - **Broker / Bus:** [service]
132
+ - **Topics / Streams / Queues:** [list]
133
+
134
+ ### Event Contract: [Topic / Event Name]
135
+ **Trace to:** [FEAT-01 / AC-01]
136
+
137
+ - **Producer:** [service/component]
138
+ - **Consumer:** [service/component]
139
+ - **Payload Schema:** [fields/example]
140
+ - **Ordering / Partition Key:** [rules]
141
+ - **Delivery Guarantee:** [at-least-once / exactly-once / best effort]
142
+ - **Retry / Dead-letter / Deduplication:** [rules]
143
+ - **Security / Signature / Replay:** [controls]
144
+
145
+ ## Assumptions & Open Questions
146
+ - [Unresolved API assumption or question]
147
+ - [Decision still pending confirmation]