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.
- package/.agents/legacy-payloads.json +22 -0
- package/{skills-lock.json → .agents/macca-lock.json} +4 -2
- package/.agents/macca-managed-skills.txt +4 -2
- package/.agents/skills/_shared/references/additional-skills.md +30 -0
- package/.agents/skills/_shared/references/brainstorm-session.md +42 -11
- package/.agents/skills/_shared/references/config-mutation.md +25 -0
- package/.agents/skills/_shared/references/finding-format.md +25 -0
- package/.agents/skills/_shared/references/fix-mode.md +39 -0
- package/.agents/skills/_shared/references/human-loop.md +3 -1
- package/.agents/skills/_shared/references/implementation-principles.md +19 -0
- package/.agents/skills/_shared/references/invocation-policy.md +39 -0
- package/.agents/skills/_shared/references/language-config.md +15 -0
- package/.agents/skills/_shared/references/output-ownership.md +4 -2
- package/.agents/skills/_shared/references/runtime-config.md +7 -168
- package/.agents/skills/_shared/references/skill-catalog.md +34 -0
- package/.agents/skills/_shared/scripts/validate-skills.py +106 -4
- package/.agents/skills/add-feature/SKILL.md +10 -7
- package/.agents/skills/brainstorm-api/SKILL.md +49 -194
- package/.agents/skills/brainstorm-api/assets/api.template.md +147 -0
- package/.agents/skills/brainstorm-architecture/SKILL.md +22 -127
- package/.agents/skills/brainstorm-architecture/assets/architecture.template.md +135 -0
- package/.agents/skills/brainstorm-prd/SKILL.md +19 -102
- package/.agents/skills/brainstorm-prd/assets/PRD.template.md +106 -0
- package/.agents/skills/brainstorm-rules/SKILL.md +17 -151
- package/.agents/skills/brainstorm-rules/assets/rules.template.md +127 -0
- package/.agents/skills/brainstorm-schema/SKILL.md +49 -115
- package/.agents/skills/brainstorm-schema/assets/schema.template.md +109 -0
- package/.agents/skills/brainstorm-styleguide/SKILL.md +19 -134
- package/.agents/skills/brainstorm-styleguide/assets/StyleGuide.template.md +147 -0
- package/.agents/skills/brainstorm-task/SKILL.md +22 -107
- package/.agents/skills/brainstorm-task/assets/Task.template.md +113 -0
- package/.agents/skills/bug-fix/SKILL.md +45 -54
- package/.agents/skills/code-review/SKILL.md +26 -19
- package/.agents/skills/code-review/references/review-checklist.md +24 -26
- package/.agents/skills/developer/SKILL.md +25 -39
- package/.agents/skills/developer/references/close-phase.md +25 -0
- package/.agents/skills/developer/references/execute-task.md +69 -0
- package/.agents/skills/developer/references/onboarding.md +47 -0
- package/.agents/skills/help/SKILL.md +12 -13
- package/.agents/skills/meet/SKILL.md +168 -0
- package/.agents/skills/quick-dev/SKILL.md +209 -0
- package/.agents/skills/release-readiness/SKILL.md +149 -0
- package/.agents/skills/spec-audit/SKILL.md +37 -22
- package/.agents/skills/spec-compliance/SKILL.md +41 -40
- package/.agents/skills/spec-init/SKILL.md +29 -14
- package/README.md +253 -170
- package/bin/macca-method.js +785 -91
- package/flow.webp +0 -0
- package/image-macca-method.webp +0 -0
- package/package.json +13 -6
- package/scripts/run-skill-validator.js +24 -0
- package/scripts/test-install.js +398 -0
- package/scripts/test-upgrade-legacy.js +107 -0
- package/scripts/validate-skill-behavior.js +124 -0
- package/.agents/skills/developer/references/execution-workflow.md +0 -322
- 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
|
-
|
|
11
|
-
|
|
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
|
|
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:
|
|
4
|
-
|
|
5
|
-
|
|
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/
|
|
16
|
+
1. Read `../_shared/references/language-config.md`.
|
|
15
17
|
2. Read `../_shared/references/output-ownership.md`.
|
|
16
|
-
3.
|
|
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
|
-
- **
|
|
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. **
|
|
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:
|
|
4
|
-
|
|
5
|
-
|
|
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/
|
|
38
|
-
2. Read `../_shared/references/
|
|
39
|
-
3. Read `../_shared/references/
|
|
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 `
|
|
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
|
|
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.
|
|
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
|
-
|
|
81
|
-
|
|
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
|
-
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
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
|
|
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.
|
|
109
|
-
*"What
|
|
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
|
-
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
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
|
|
129
|
+
*"For each operation, what input is accepted and what result or event is produced? Include protocol-native examples."*
|
|
119
130
|
|
|
120
|
-
Collect
|
|
121
|
-
- **
|
|
122
|
-
- **
|
|
123
|
-
- **
|
|
124
|
-
-
|
|
125
|
-
-
|
|
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
|
-
*"
|
|
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
|
-
|
|
240
|
-
**
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
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
|
-
|
|
150
|
+
After discovery is complete and immediately before generating `project-context/api.md`, read `assets/api.template.md`.
|
|
293
151
|
|
|
294
|
-
|
|
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]
|