create-agent-room 1.2.1
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 +229 -0
- package/bin/cli.js +186 -0
- package/examples/python-project/.agent-room.json +14 -0
- package/examples/python-project/AGENTS.md +32 -0
- package/examples/rust-project/.agent-room.json +12 -0
- package/examples/rust-project/AGENTS.md +32 -0
- package/lib/color.js +31 -0
- package/lib/fsutil.js +218 -0
- package/lib/init.js +660 -0
- package/lib/lint-sessions.js +278 -0
- package/lib/metrics.js +190 -0
- package/lib/pr.js +176 -0
- package/lib/prompt.js +20 -0
- package/lib/session-utils.js +213 -0
- package/lib/sync.js +138 -0
- package/lib/validate.js +179 -0
- package/package.json +48 -0
- package/templates/.agent-room/anti-patterns.md +22 -0
- package/templates/.agent-room/coordination/handoff-protocol.md +60 -0
- package/templates/.agent-room/coordination/scope-boundaries.md +57 -0
- package/templates/.agent-room/coordination/session-log-format.md +62 -0
- package/templates/.agent-room/decisions.md +17 -0
- package/templates/.agent-room/guardrails.json +23 -0
- package/templates/.agent-room/guardrails.md +56 -0
- package/templates/.agent-room/principles.md +306 -0
- package/templates/.agent-room/sessions/.gitkeep +4 -0
- package/templates/.agent-room/skills/brainstorming.md +64 -0
- package/templates/.agent-room/skills/closing-the-loop.md +67 -0
- package/templates/.agent-room/skills/systematic-debugging.md +85 -0
- package/templates/.agent-room/skills/test-driven-development.md +100 -0
- package/templates/.agent-room/skills/verification-before-completion.md +56 -0
- package/templates/.agent-room/skills/writing-plans.md +87 -0
- package/templates/.agent-room/workflow-classifier.md +127 -0
- package/templates/AGENTS.md.tmpl +85 -0
- package/templates/adapters/CLAUDE.md.tmpl +38 -0
- package/templates/adapters/claude-hooks/close-the-loop-check.js +96 -0
- package/templates/adapters/clinerules.tmpl +14 -0
- package/templates/adapters/codexrules.tmpl +45 -0
- package/templates/adapters/cursorrules.tmpl +14 -0
- package/templates/adapters/git-hooks/guardrails-check.js +140 -0
- package/templates/adapters/git-hooks/pre-commit.tmpl +43 -0
- package/templates/adapters/windsurfrules.tmpl +14 -0
- package/templates/docs/plans/.gitkeep +0 -0
- package/templates/skill-packs/api-design/api-design.md +152 -0
- package/templates/skill-packs/code-review/code-review.md +113 -0
- package/templates/skill-packs/database/database-migrations.md +123 -0
- package/templates/skill-packs/documentation/documentation.md +155 -0
- package/templates/skill-packs/observability/observability.md +128 -0
- package/templates/skill-packs/performance/performance-optimization.md +150 -0
- package/templates/skill-packs/release/release-management.md +145 -0
- package/templates/skill-packs/security/security-principles.md +127 -0
- package/templates/skill-packs/testing/integration-testing.md +127 -0
- package/templates/stacks/python/.agent-room/skills/python-testing.md +59 -0
- package/templates/stacks/python/AGENTS.md.tmpl +35 -0
- package/templates/stacks/react/.agent-room/skills/react-component-testing.md +76 -0
- package/templates/stacks/react/AGENTS.md.tmpl +37 -0
- package/templates/stacks/typescript/.agent-room/skills/typescript-testing.md +63 -0
- package/templates/stacks/typescript/AGENTS.md.tmpl +36 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: documentation
|
|
3
|
+
description: "Use when writing inline comments, doc comments, READMEs, API documentation, architecture decision records, or operational runbooks."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Documentation
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Documentation is not an afterthought — it's a deliverable. Code without
|
|
11
|
+
documentation is code that the next person (human or agent) will
|
|
12
|
+
misunderstand, misuse, or rewrite from scratch. But bad documentation is
|
|
13
|
+
worse than no documentation — it creates false confidence.
|
|
14
|
+
|
|
15
|
+
## The iron law
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
DOCUMENT THE WHY, NOT THE WHAT
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Code shows *what* happens. Documentation explains *why* it happens that
|
|
22
|
+
way, *what alternatives were rejected*, and *what assumptions hold.* If
|
|
23
|
+
the documentation just restates the code, it adds maintenance burden
|
|
24
|
+
without value.
|
|
25
|
+
|
|
26
|
+
## When to document what
|
|
27
|
+
|
|
28
|
+
### Inline comments
|
|
29
|
+
|
|
30
|
+
Use for non-obvious logic — the "why" behind a decision.
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
BAD: // increment counter
|
|
34
|
+
counter++;
|
|
35
|
+
|
|
36
|
+
GOOD: // Rate limiter uses a sliding window. We increment here rather than
|
|
37
|
+
// in the middleware because failed auth attempts should count against
|
|
38
|
+
// the limit even if the request is rejected before reaching the handler.
|
|
39
|
+
counter++;
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Don't comment obvious code.** If the code is so unclear that it needs a
|
|
43
|
+
comment explaining *what* it does, refactor the code to be clearer instead.
|
|
44
|
+
|
|
45
|
+
### Doc comments (JSDoc, typedoc, docstrings)
|
|
46
|
+
|
|
47
|
+
Use for every public function, class, and module that other code consumes.
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
/**
|
|
51
|
+
* Resolves a user's effective permissions by merging role-based
|
|
52
|
+
* permissions with any user-specific overrides.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} userId - The user ID to resolve permissions for.
|
|
55
|
+
* @param {string} resourceId - The resource being accessed.
|
|
56
|
+
* @returns {Permission[]} Merged permissions, with user overrides
|
|
57
|
+
* taking precedence over role defaults.
|
|
58
|
+
* @throws {NotFoundError} If the user does not exist.
|
|
59
|
+
*/
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Include:
|
|
63
|
+
- What the function does (one sentence).
|
|
64
|
+
- Parameter descriptions with types.
|
|
65
|
+
- Return value description.
|
|
66
|
+
- Exceptions/errors thrown and when.
|
|
67
|
+
- Any side effects (writes to database, sends email, modifies global
|
|
68
|
+
state).
|
|
69
|
+
|
|
70
|
+
### README sections
|
|
71
|
+
|
|
72
|
+
Every project's README should contain at minimum:
|
|
73
|
+
1. **What it is** — one paragraph explaining the project's purpose.
|
|
74
|
+
2. **Quick start** — how to install, configure, and run.
|
|
75
|
+
3. **Development setup** — how to set up a local development environment.
|
|
76
|
+
4. **Testing** — how to run the test suite.
|
|
77
|
+
5. **Architecture overview** — high-level description of the system
|
|
78
|
+
structure (link to a diagram if complex).
|
|
79
|
+
|
|
80
|
+
### Architecture Decision Records (ADRs)
|
|
81
|
+
|
|
82
|
+
Use for significant architecture or design decisions that someone could
|
|
83
|
+
reasonably ask "why did you do it this way?"
|
|
84
|
+
|
|
85
|
+
**Format** (stored in `docs/decisions/` or `.agent-room/decisions.md`):
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
### YYYY-MM-DD — Short title
|
|
89
|
+
|
|
90
|
+
**Status:** Accepted / Superseded by [link] / Deprecated
|
|
91
|
+
|
|
92
|
+
**Context:** What situation or problem prompted this decision?
|
|
93
|
+
|
|
94
|
+
**Decision:** What was decided and how?
|
|
95
|
+
|
|
96
|
+
**Consequences:** What are the trade-offs? What becomes easier? What
|
|
97
|
+
becomes harder?
|
|
98
|
+
|
|
99
|
+
**Alternatives considered:**
|
|
100
|
+
- Option A: description. Rejected because...
|
|
101
|
+
- Option B: description. Rejected because...
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Operational runbooks
|
|
105
|
+
|
|
106
|
+
For any system that runs in production, document the operational
|
|
107
|
+
procedures:
|
|
108
|
+
|
|
109
|
+
```markdown
|
|
110
|
+
## Runbook: [Service/Component Name]
|
|
111
|
+
|
|
112
|
+
### Health check
|
|
113
|
+
- URL: `GET /health`
|
|
114
|
+
- Expected: 200 with `{"status": "ok"}`
|
|
115
|
+
- If failing: Check database connectivity, then check [dependency].
|
|
116
|
+
|
|
117
|
+
### Common failure modes
|
|
118
|
+
1. **High memory usage:** Usually caused by [X]. Fix: [Y].
|
|
119
|
+
2. **Slow response times:** Check [Z] dashboard. If [metric] > [threshold],
|
|
120
|
+
scale horizontally.
|
|
121
|
+
|
|
122
|
+
### Deployment
|
|
123
|
+
- Deploy via: `[command]`
|
|
124
|
+
- Rollback via: `[command]`
|
|
125
|
+
- Post-deploy verification: `[check]`
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## API documentation
|
|
129
|
+
|
|
130
|
+
For services that expose APIs:
|
|
131
|
+
|
|
132
|
+
- Use OpenAPI/Swagger for REST APIs. Keep the spec in sync with the code
|
|
133
|
+
(generate from annotations, or validate the spec in CI).
|
|
134
|
+
- Document every endpoint, every parameter, every response shape, every
|
|
135
|
+
error code.
|
|
136
|
+
- Include example requests and responses for each endpoint.
|
|
137
|
+
- Document authentication requirements and rate limits.
|
|
138
|
+
|
|
139
|
+
## Documentation anti-patterns
|
|
140
|
+
|
|
141
|
+
| Anti-pattern | Problem | Fix |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| "Self-documenting code" as an excuse | Not all "why" is visible in code | Write the comments the code can't express |
|
|
144
|
+
| Documentation in a wiki nobody reads | Out of sync within weeks | Keep docs next to the code they describe |
|
|
145
|
+
| Stale README | Worse than no README — misleads people | Update README as part of the PR that changes behavior |
|
|
146
|
+
| TODO comments without owners or dates | They accumulate forever | Format: `TODO(username, YYYY-MM-DD): description` |
|
|
147
|
+
| Generated docs with no curation | Noise overwhelms signal | Write summaries, examples, and guides on top of generated reference |
|
|
148
|
+
|
|
149
|
+
## Red flags — stop and document
|
|
150
|
+
|
|
151
|
+
A new team member asks "how does X work?" and nobody can point to a
|
|
152
|
+
document · a production incident requires reading source code to diagnose ·
|
|
153
|
+
a function has 8 parameters and no doc comment · the README's "quick start"
|
|
154
|
+
doesn't work · an ADR is missing for a decision that took the team a week
|
|
155
|
+
to make.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: observability
|
|
3
|
+
description: "Use when adding logging, metrics, tracing, alerting, or error handling to applications — or when deciding what to observe and how."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Observability
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Observability is not "add console.log everywhere." It's a disciplined
|
|
11
|
+
approach to making systems understandable in production — where you can't
|
|
12
|
+
attach a debugger, set breakpoints, or reproduce bugs on demand. Good
|
|
13
|
+
observability answers: "What happened, where, when, and why?" from the
|
|
14
|
+
logs and metrics alone, without needing to read the source code.
|
|
15
|
+
|
|
16
|
+
## The iron law
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
EVERY PRODUCTION ERROR MUST BE TRACEABLE TO A ROOT CAUSE WITHOUT READING SOURCE CODE
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
If an error fires in production and the on-call engineer needs to read
|
|
23
|
+
the codebase to understand what went wrong, the observability is
|
|
24
|
+
insufficient. The log entry, metric, or trace should contain enough
|
|
25
|
+
context to diagnose the issue.
|
|
26
|
+
|
|
27
|
+
## The three pillars
|
|
28
|
+
|
|
29
|
+
### 1. Logs — what happened
|
|
30
|
+
|
|
31
|
+
Use structured logging (JSON), not unstructured strings.
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
BAD: console.log("User login failed")
|
|
35
|
+
GOOD: logger.warn({ event: "auth.login_failed", userId: "u_123",
|
|
36
|
+
reason: "invalid_password", ip: req.ip, requestId: req.id })
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**What to log:**
|
|
40
|
+
- Business events: user signup, order placed, payment processed.
|
|
41
|
+
- Errors with full context: what was attempted, what failed, what input
|
|
42
|
+
caused it.
|
|
43
|
+
- Security events: failed login attempts, permission denials, token
|
|
44
|
+
expirations.
|
|
45
|
+
|
|
46
|
+
**What NOT to log:**
|
|
47
|
+
- Secrets, passwords, tokens, full credit card numbers. Ever.
|
|
48
|
+
- Success cases for high-frequency operations (every successful health
|
|
49
|
+
check, every cache hit). Use metrics for these.
|
|
50
|
+
- Full request/response bodies in production (unless explicitly in a
|
|
51
|
+
debug mode with PII scrubbing).
|
|
52
|
+
|
|
53
|
+
**Correlation IDs:** Generate a unique `requestId` at the entry point of
|
|
54
|
+
every request. Pass it through every function call, every service-to-
|
|
55
|
+
service call, and include it in every log entry. This lets you trace a
|
|
56
|
+
single user action across multiple services and log entries.
|
|
57
|
+
|
|
58
|
+
### 2. Metrics — how much
|
|
59
|
+
|
|
60
|
+
Metrics are aggregated numbers over time. Use them for trends, alerting,
|
|
61
|
+
and dashboards — not for debugging individual requests.
|
|
62
|
+
|
|
63
|
+
**The four golden signals (from Google SRE):**
|
|
64
|
+
- **Latency:** How long requests take. Track p50, p95, p99.
|
|
65
|
+
- **Traffic:** How many requests per second (or per minute).
|
|
66
|
+
- **Errors:** How many requests fail (as a rate, not a count).
|
|
67
|
+
- **Saturation:** How full are your resources (CPU, memory, disk, queue
|
|
68
|
+
depth).
|
|
69
|
+
|
|
70
|
+
**Naming convention:** Use dot-separated namespaces.
|
|
71
|
+
```
|
|
72
|
+
api.users.request_duration_ms
|
|
73
|
+
api.users.error_count
|
|
74
|
+
db.connections.active
|
|
75
|
+
queue.orders.depth
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 3. Traces — where it went
|
|
79
|
+
|
|
80
|
+
Distributed traces show the path of a request across services. Use them
|
|
81
|
+
when a single user action touches multiple services and you need to find
|
|
82
|
+
which one is slow or failing.
|
|
83
|
+
|
|
84
|
+
- Instrument service boundaries (HTTP calls, queue publishes, database
|
|
85
|
+
queries).
|
|
86
|
+
- Include trace IDs in log entries so you can correlate logs with traces.
|
|
87
|
+
- Don't trace everything in production — sample at 1-10% for normal
|
|
88
|
+
traffic, 100% for errors.
|
|
89
|
+
|
|
90
|
+
## Error classification
|
|
91
|
+
|
|
92
|
+
Not all errors are equal. Classify them to determine the response:
|
|
93
|
+
|
|
94
|
+
| Category | Meaning | Response |
|
|
95
|
+
| --- | --- | --- |
|
|
96
|
+
| Transient | Temporary failure (network timeout, rate limit) | Retry with backoff |
|
|
97
|
+
| Permanent | Will never succeed (invalid input, missing resource) | Return error to caller, don't retry |
|
|
98
|
+
| Fatal | System cannot continue (out of memory, corrupt state) | Alert immediately, escalate |
|
|
99
|
+
|
|
100
|
+
**Anti-pattern:** Retrying permanent errors. If the input is invalid, it
|
|
101
|
+
will be invalid on the next attempt too. Check the error type before
|
|
102
|
+
retrying.
|
|
103
|
+
|
|
104
|
+
## Alert design
|
|
105
|
+
|
|
106
|
+
Alerts should be **actionable, not noisy.**
|
|
107
|
+
|
|
108
|
+
**Good alert:** "API error rate exceeded 5% for 5 consecutive minutes.
|
|
109
|
+
Dashboard: [link]. Runbook: [link]."
|
|
110
|
+
|
|
111
|
+
**Bad alert:** "Error occurred." (Which error? Where? What should I do?)
|
|
112
|
+
|
|
113
|
+
**Rules for alerts:**
|
|
114
|
+
- Every alert must have a runbook (even if it's one paragraph).
|
|
115
|
+
- Alert on symptoms (error rate, latency), not causes (CPU usage — unless
|
|
116
|
+
it's at 95%+).
|
|
117
|
+
- Use severity levels: critical (wake someone up), warning (investigate
|
|
118
|
+
during business hours), info (no action needed, for dashboards only).
|
|
119
|
+
- If an alert fires more than 3 times without action, it's noise — fix
|
|
120
|
+
the underlying issue or tune the threshold.
|
|
121
|
+
|
|
122
|
+
## Red flags — stop and rethink
|
|
123
|
+
|
|
124
|
+
`console.log(error)` without context · logging PII or secrets ·
|
|
125
|
+
alerting on every single error instead of error rates · no correlation
|
|
126
|
+
IDs across services · metrics without dashboards (data collected but
|
|
127
|
+
never reviewed) · catch-and-swallow error handling (`catch (e) {}`) ·
|
|
128
|
+
"we'll add observability later."
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance-optimization
|
|
3
|
+
description: "Use when investigating slow code, optimizing queries, reducing load times, or making architectural decisions that affect throughput and latency."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Performance Optimization
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Performance optimization without measurement is superstition. The most
|
|
11
|
+
common performance mistake agents make is optimizing code that isn't slow
|
|
12
|
+
while ignoring code that is. Measure first, optimize the bottleneck,
|
|
13
|
+
measure again.
|
|
14
|
+
|
|
15
|
+
## The iron law
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
MEASURE BEFORE AND AFTER EVERY OPTIMIZATION
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
If you can't measure the improvement, you don't know if you improved
|
|
22
|
+
anything. Optimizations that aren't measured are guesses — and guesses
|
|
23
|
+
frequently make things worse by adding complexity without benefit.
|
|
24
|
+
|
|
25
|
+
## The optimization protocol
|
|
26
|
+
|
|
27
|
+
### Step 1: Define the metric
|
|
28
|
+
|
|
29
|
+
Before optimizing, define what "fast enough" means:
|
|
30
|
+
- **API latency:** p50, p95, p99 response times. p95 matters more than
|
|
31
|
+
average — averages hide tail latency.
|
|
32
|
+
- **Page load:** Time to First Byte (TTFB), Largest Contentful Paint
|
|
33
|
+
(LCP), Time to Interactive (TTI).
|
|
34
|
+
- **Throughput:** Requests per second the system can sustain.
|
|
35
|
+
- **Resource usage:** Memory, CPU, disk I/O under expected load.
|
|
36
|
+
|
|
37
|
+
### Step 2: Profile, don't guess
|
|
38
|
+
|
|
39
|
+
- Use profiling tools (flame graphs, query analyzers, Chrome DevTools
|
|
40
|
+
Performance tab), not intuition.
|
|
41
|
+
- Find the actual bottleneck. Common surprise: "I thought the API was
|
|
42
|
+
slow but the bottleneck was a DNS lookup, not the database query."
|
|
43
|
+
- Profile under realistic conditions (production-like data volumes, not
|
|
44
|
+
10 rows in a test database).
|
|
45
|
+
|
|
46
|
+
### Step 3: Optimize the bottleneck
|
|
47
|
+
|
|
48
|
+
Fix the measured bottleneck. Don't optimize adjacent code "while you're
|
|
49
|
+
in there."
|
|
50
|
+
|
|
51
|
+
### Step 4: Measure again
|
|
52
|
+
|
|
53
|
+
Run the same benchmark. Compare results. If the improvement is
|
|
54
|
+
statistically insignificant, revert — the optimization added complexity
|
|
55
|
+
without value.
|
|
56
|
+
|
|
57
|
+
## Common performance problems and fixes
|
|
58
|
+
|
|
59
|
+
### N+1 queries
|
|
60
|
+
|
|
61
|
+
**The problem:** A loop fetches related data one row at a time.
|
|
62
|
+
```
|
|
63
|
+
users = db.query("SELECT * FROM users")
|
|
64
|
+
for user in users:
|
|
65
|
+
orders = db.query("SELECT * FROM orders WHERE user_id = ?", user.id)
|
|
66
|
+
```
|
|
67
|
+
100 users = 101 queries. 10,000 users = 10,001 queries.
|
|
68
|
+
|
|
69
|
+
**The fix:** Eager load or batch fetch.
|
|
70
|
+
```
|
|
71
|
+
users = db.query("SELECT * FROM users")
|
|
72
|
+
user_ids = [u.id for u in users]
|
|
73
|
+
orders = db.query("SELECT * FROM orders WHERE user_id IN (?)", user_ids)
|
|
74
|
+
```
|
|
75
|
+
100 users = 2 queries. 10,000 users = 2 queries.
|
|
76
|
+
|
|
77
|
+
### Unbounded queries
|
|
78
|
+
|
|
79
|
+
**The problem:** A query fetches all rows without a LIMIT.
|
|
80
|
+
```
|
|
81
|
+
SELECT * FROM events -- 50 million rows
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**The fix:** Always paginate. Use LIMIT/OFFSET for small datasets,
|
|
85
|
+
cursor-based pagination for large ones. Every list query must have a
|
|
86
|
+
bound.
|
|
87
|
+
|
|
88
|
+
### Missing indexes
|
|
89
|
+
|
|
90
|
+
**The problem:** A WHERE clause or JOIN on an unindexed column causes a
|
|
91
|
+
full table scan.
|
|
92
|
+
|
|
93
|
+
**The fix:** Add an index on columns used in WHERE, JOIN, and ORDER BY
|
|
94
|
+
clauses. But don't add indexes speculatively — each index slows writes
|
|
95
|
+
and uses storage. Add when you have a measured slow query.
|
|
96
|
+
|
|
97
|
+
### Premature caching
|
|
98
|
+
|
|
99
|
+
**The problem:** Caching added before measuring whether the underlying
|
|
100
|
+
operation is actually slow. The cache adds invalidation complexity,
|
|
101
|
+
stale data risks, and memory pressure — for a query that takes 5ms.
|
|
102
|
+
|
|
103
|
+
**The fix:** Cache only when:
|
|
104
|
+
1. The operation is measurably slow (>100ms for user-facing, >1s for
|
|
105
|
+
background).
|
|
106
|
+
2. The data changes infrequently relative to read frequency.
|
|
107
|
+
3. Staleness is acceptable for the use case.
|
|
108
|
+
|
|
109
|
+
When caching:
|
|
110
|
+
- Set explicit TTLs. Never cache without an expiration.
|
|
111
|
+
- Document the invalidation strategy. "Cache invalidation" is where most
|
|
112
|
+
caching bugs live.
|
|
113
|
+
- Monitor hit rates. A cache with <80% hit rate is probably not worth the
|
|
114
|
+
complexity.
|
|
115
|
+
|
|
116
|
+
### Frontend bundle bloat
|
|
117
|
+
|
|
118
|
+
**The problem:** A 2MB JavaScript bundle for a page that needs 200KB of
|
|
119
|
+
logic.
|
|
120
|
+
|
|
121
|
+
**The fix:**
|
|
122
|
+
- Audit with `webpack-bundle-analyzer`, `source-map-explorer`, or
|
|
123
|
+
equivalent.
|
|
124
|
+
- Code-split by route. Users shouldn't download the admin dashboard code
|
|
125
|
+
when viewing the login page.
|
|
126
|
+
- Lazy-load below-the-fold components.
|
|
127
|
+
- Replace heavy libraries with lighter alternatives when the full feature
|
|
128
|
+
set isn't needed.
|
|
129
|
+
|
|
130
|
+
## Performance budgets
|
|
131
|
+
|
|
132
|
+
Set budgets and enforce them in CI:
|
|
133
|
+
|
|
134
|
+
| Metric | Budget | Enforcement |
|
|
135
|
+
| --- | --- | --- |
|
|
136
|
+
| API p95 latency | <200ms | Load test in CI, alert on regression |
|
|
137
|
+
| Bundle size | <250KB gzipped | Build step fails if exceeded |
|
|
138
|
+
| Database query count per request | <10 | Logging + review |
|
|
139
|
+
| LCP | <2.5s | Lighthouse CI |
|
|
140
|
+
|
|
141
|
+
Budgets prevent gradual degradation. Without them, performance erodes
|
|
142
|
+
one "small" addition at a time until the system is unusably slow.
|
|
143
|
+
|
|
144
|
+
## Red flags — stop and measure
|
|
145
|
+
|
|
146
|
+
"This should be faster" without data · optimizing code that profiling
|
|
147
|
+
shows isn't in the hot path · adding a cache for a 5ms operation ·
|
|
148
|
+
"premature optimization is the root of all evil" used to justify never
|
|
149
|
+
measuring · rewriting in a "faster language" before profiling the current
|
|
150
|
+
implementation.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-management
|
|
3
|
+
description: "Use when preparing release commits, tagging, bumping version numbers, compiling changelogs, or deciding whether a change is safe to release."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Release Management
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Releasing software should be automated, reproducible, and traceably
|
|
11
|
+
documented. A release is not "push to main and hope" — it's a controlled
|
|
12
|
+
process with validation gates, a rollback plan, and post-release
|
|
13
|
+
verification.
|
|
14
|
+
|
|
15
|
+
## The iron law
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
NO RELEASE WITHOUT A ROLLBACK PLAN
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Before tagging a release, you must be able to answer: "If this breaks
|
|
22
|
+
production, what do we do in the next 5 minutes?" If the answer is "I
|
|
23
|
+
don't know," the release is not ready.
|
|
24
|
+
|
|
25
|
+
## Release process
|
|
26
|
+
|
|
27
|
+
### 1. Pre-release validation checklist
|
|
28
|
+
|
|
29
|
+
Before bumping the version, confirm:
|
|
30
|
+
|
|
31
|
+
- [ ] All tests pass on the release branch (not just locally — in CI)
|
|
32
|
+
- [ ] Linter is clean with zero warnings
|
|
33
|
+
- [ ] No high/critical dependency audit findings
|
|
34
|
+
- [ ] Breaking changes are documented with migration instructions
|
|
35
|
+
- [ ] Database migrations are backward-compatible (see below)
|
|
36
|
+
- [ ] Feature flags for incomplete features are defaulted to off
|
|
37
|
+
- [ ] The changelog is complete and reviewed
|
|
38
|
+
|
|
39
|
+
If any box is unchecked, the release is not ready. Don't ship with
|
|
40
|
+
"we'll fix it in the next release."
|
|
41
|
+
|
|
42
|
+
### 2. Version bump
|
|
43
|
+
|
|
44
|
+
Increment the version in configuration files (`package.json`, `setup.py`,
|
|
45
|
+
`Cargo.toml`, etc.) according to Semantic Versioning:
|
|
46
|
+
|
|
47
|
+
| Change type | Version bump | Example |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| Bug fixes, patches | PATCH | 1.2.3 → 1.2.4 |
|
|
50
|
+
| New features (backward-compatible) | MINOR | 1.2.3 → 1.3.0 |
|
|
51
|
+
| Breaking changes | MAJOR | 1.2.3 → 2.0.0 |
|
|
52
|
+
|
|
53
|
+
**When in doubt, it's a MINOR.** PATCH is only for pure bug fixes with
|
|
54
|
+
no new behavior. If you added a flag, an option, a new endpoint — it's
|
|
55
|
+
MINOR, even if it "feels small."
|
|
56
|
+
|
|
57
|
+
### 3. Changelog generation
|
|
58
|
+
|
|
59
|
+
Compile changes into `CHANGELOG.md`, grouped by type:
|
|
60
|
+
|
|
61
|
+
```markdown
|
|
62
|
+
## [1.3.0] - 2025-03-15
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
- Webhook notification support for order status changes (#142)
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
- Increased default pagination limit from 20 to 50 (#138)
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
- Timezone conversion error in reporting module (#145)
|
|
72
|
+
|
|
73
|
+
### Breaking
|
|
74
|
+
- Removed deprecated `/api/v1/users` endpoint (#130). Use `/api/v2/users`.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Write entries for humans, not for commit logs. "Fixed #145" is not a
|
|
78
|
+
changelog entry. "Fixed timezone conversion error that caused incorrect
|
|
79
|
+
daily totals in the reporting module" is.
|
|
80
|
+
|
|
81
|
+
### 4. Release commit and tag
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git add CHANGELOG.md package.json # (or equivalent version files)
|
|
85
|
+
git commit -m "chore(release): version {{VERSION}}"
|
|
86
|
+
git tag -a v{{VERSION}} -m "Version {{VERSION}}"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 5. Merge to main
|
|
90
|
+
|
|
91
|
+
Ensure all release updates are merged into the default branch
|
|
92
|
+
`{{DEFAULT_BRANCH}}`. The tagged commit must be reachable from the
|
|
93
|
+
default branch.
|
|
94
|
+
|
|
95
|
+
## Rollback plan
|
|
96
|
+
|
|
97
|
+
Every release must document its rollback strategy before shipping:
|
|
98
|
+
|
|
99
|
+
- **Stateless services:** Rollback is redeploying the previous version.
|
|
100
|
+
Confirm the previous Docker image / artifact is still available.
|
|
101
|
+
- **Database migrations included:** Rollback requires a reverse
|
|
102
|
+
migration. Write and test the reverse migration *before* releasing.
|
|
103
|
+
If the migration is not reversible (dropped column, data transformation),
|
|
104
|
+
document the manual recovery procedure.
|
|
105
|
+
- **Breaking API changes:** Rollback may require client-side changes.
|
|
106
|
+
Use API versioning to maintain the old endpoint during the transition
|
|
107
|
+
period.
|
|
108
|
+
|
|
109
|
+
## Database migration safety
|
|
110
|
+
|
|
111
|
+
Migrations are the riskiest part of most releases. Rules:
|
|
112
|
+
|
|
113
|
+
1. **Forward-only in production.** Never hand-edit a production database.
|
|
114
|
+
2. **Backward-compatible by default.** The old code should still work
|
|
115
|
+
after the migration runs (deploy migration first, then new code).
|
|
116
|
+
3. **Additive changes are safe:** new tables, new columns (nullable or
|
|
117
|
+
with defaults), new indexes.
|
|
118
|
+
4. **Destructive changes require a multi-step release:**
|
|
119
|
+
- Release 1: Add the new column, start writing to both old and new.
|
|
120
|
+
- Release 2: Backfill data, switch reads to new column.
|
|
121
|
+
- Release 3: Remove the old column.
|
|
122
|
+
5. **Index creation:** Use `CREATE INDEX CONCURRENTLY` (Postgres) or
|
|
123
|
+
equivalent. Large indexes on production tables can lock writes.
|
|
124
|
+
|
|
125
|
+
## Feature flag coordination
|
|
126
|
+
|
|
127
|
+
When releasing behind feature flags:
|
|
128
|
+
|
|
129
|
+
- Default new flags to **off** in production.
|
|
130
|
+
- The release changelog should note which flags are included and their
|
|
131
|
+
default state.
|
|
132
|
+
- Remove flags promptly after the feature is fully rolled out. Stale
|
|
133
|
+
flags are technical debt that compounds — each flag doubles the number
|
|
134
|
+
of code paths to test.
|
|
135
|
+
|
|
136
|
+
## Post-release monitoring
|
|
137
|
+
|
|
138
|
+
After deploying:
|
|
139
|
+
|
|
140
|
+
1. Watch error rates for 15 minutes. Any spike → investigate immediately.
|
|
141
|
+
2. Check key metrics (latency, throughput, error rate) against the
|
|
142
|
+
pre-release baseline.
|
|
143
|
+
3. If metrics degrade beyond acceptable thresholds, execute the rollback
|
|
144
|
+
plan. Don't debug in production under pressure — roll back first,
|
|
145
|
+
investigate second.
|