nightytidy 0.3.7 → 0.3.9
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/bin/nightytidy.js +1 -1
- package/package.json +1 -1
- package/src/agent/git-integration.js +4 -1
- package/src/claude.js +1 -1
- package/src/prompts/manifest.json +138 -138
- package/src/prompts/steps/02-test-coverage.md +181 -181
- package/src/prompts/steps/03-test-hardening.md +181 -181
- package/src/prompts/steps/04-test-architecture.md +130 -130
- package/src/prompts/steps/05-test-consolidation.md +165 -165
- package/src/prompts/steps/06-test-quality.md +211 -211
- package/src/prompts/steps/07-api-design.md +165 -165
- package/src/prompts/steps/08-security-sweep.md +207 -207
- package/src/prompts/steps/09-dependency-health.md +217 -217
- package/src/prompts/steps/10-codebase-cleanup.md +189 -189
- package/src/prompts/steps/11-crosscutting-concerns.md +196 -196
- package/src/prompts/steps/12-file-decomposition.md +263 -263
- package/src/prompts/steps/13-code-elegance.md +329 -329
- package/src/prompts/steps/14-architectural-complexity.md +297 -297
- package/src/prompts/steps/15-type-safety.md +192 -192
- package/src/prompts/steps/16-logging-error-message.md +173 -173
- package/src/prompts/steps/17-data-integrity.md +139 -139
- package/src/prompts/steps/18-performance.md +183 -183
- package/src/prompts/steps/19-cost-resource-optimization.md +136 -136
- package/src/prompts/steps/20-error-recovery.md +145 -145
- package/src/prompts/steps/21-race-condition-audit.md +178 -178
- package/src/prompts/steps/22-bug-hunt.md +229 -229
- package/src/prompts/steps/23-frontend-quality.md +210 -210
- package/src/prompts/steps/24-uiux-audit.md +284 -284
- package/src/prompts/steps/25-state-management.md +170 -170
- package/src/prompts/steps/26-perceived-performance.md +190 -190
- package/src/prompts/steps/27-devops.md +165 -165
- package/src/prompts/steps/28-scheduled-job-chron-jobs.md +141 -141
- package/src/prompts/steps/29-observability.md +152 -152
- package/src/prompts/steps/30-backup-check.md +155 -155
- package/src/prompts/steps/31-product-polish-ux-friction.md +122 -122
- package/src/prompts/steps/32-feature-discovery-opportunity.md +128 -128
- package/src/prompts/steps/33-strategic-opportunities.md +217 -217
|
@@ -1,178 +1,178 @@
|
|
|
1
|
-
# Concurrency & Race Condition Audit
|
|
2
|
-
|
|
3
|
-
You are running an overnight concurrency and race condition audit. Your job: find where simultaneous operations cause data corruption, lost updates, double-processing, or inconsistent state.
|
|
4
|
-
|
|
5
|
-
This is primarily analysis and documentation. Race conditions are dangerous to "fix" without deep understanding — fix only clear-cut cases, document everything else with specific, actionable recommendations.
|
|
6
|
-
|
|
7
|
-
Work on branch `concurrency-audit-[date]`.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Global Rules
|
|
12
|
-
|
|
13
|
-
- Run tests after every change. Commit format: `fix: [concurrency protection type] in [module]`
|
|
14
|
-
- **Only fix** race conditions where the fix is clearly correct and low-risk: adding unique constraints (migration file, not run), replacing read-modify-write with atomic operations, adding `SELECT FOR UPDATE` to existing transactions, adding `WHERE` clause guards to status transitions, replacing read-compute-write cache patterns with atomic cache operations, adding missing cache invalidation to write paths, fixing invalidation ordering, adding button disable-on-submit.
|
|
15
|
-
- **Do NOT implement** overnight: distributed locking, leader election, event sourcing, global transaction isolation level changes, cache stampede protection (unless project already has a pattern), or TTL changes (unless clearly a framework default).
|
|
16
|
-
- When documenting a race condition, show the **interleaved timeline** — the specific sequence of events that causes the problem, with entity IDs and timing where relevant.
|
|
17
|
-
- Bad: "There's a race condition in the order system"
|
|
18
|
-
- Good: "In `orders_service.js:142`, two concurrent requests can both read `inventory_count=1`, both pass the `>0` check, and both decrement → `inventory_count=-1`. Fix: `SELECT FOR UPDATE` on the inventory row."
|
|
19
|
-
- For cache races, include timing windows: "DB write takes ~50ms, invalidation 10ms after → 60ms stale read window."
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Phase 1: Shared Mutable State Analysis
|
|
24
|
-
|
|
25
|
-
**Step 1: Find global and module-level mutable state**
|
|
26
|
-
Search for: global variables modified after init, module-level variables written during request handling, singletons with mutable properties, static variables that change at runtime, in-memory caches/registries read AND written during requests, module-level connection pools/rate limiters/counters.
|
|
27
|
-
|
|
28
|
-
For each: What data? Which code paths read/write it? Can two requests access it simultaneously? Consequence? (Stale read, lost update, corruption, crash?)
|
|
29
|
-
|
|
30
|
-
**Step 2: Find request-scoped state leaks**
|
|
31
|
-
Request data stored on shared objects, improperly isolated thread-local/async-context storage, middleware modifying shared state per-request, object pools retaining previous request state.
|
|
32
|
-
|
|
33
|
-
**Step 3: Fix clear-cut issues**
|
|
34
|
-
Convert mutable globals to request-scoped state where obvious. Add isolation. Make immutable what doesn't need to mutate. Document complex cases in the report.
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Phase 2: Database Race Conditions
|
|
39
|
-
|
|
40
|
-
**Step 1: Find read-modify-write patterns**
|
|
41
|
-
Code that reads a value, modifies it in application code, writes it back — counter increments, availability checks + reservation, balance updates, status transitions, list appends.
|
|
42
|
-
|
|
43
|
-
For each: Is it in a transaction? Appropriate isolation level? Optimistic concurrency (version/`updated_at`)? Pessimistic lock (`SELECT FOR UPDATE`)? What happens with two simultaneous requests right now?
|
|
44
|
-
|
|
45
|
-
**Step 2: Find check-then-act patterns**
|
|
46
|
-
Code that checks a condition then acts on it without concurrency protection — uniqueness checks without unique constraints, availability checks without locks, eligibility checks without guards.
|
|
47
|
-
|
|
48
|
-
For each: Is there a database constraint backing the check? A lock? Or just unprotected application logic?
|
|
49
|
-
|
|
50
|
-
**Step 3: Find transaction scope issues**
|
|
51
|
-
Transactions too narrow (partial protection), too broad (locks held during external API calls), external side effects inside transactions (HTTP calls, queue publishes that can't roll back), nested transaction behavior misunderstandings, missing transactions on multi-statement operations.
|
|
52
|
-
|
|
53
|
-
**Step 4: Fix safe issues**
|
|
54
|
-
Add unique constraints, replace read-modify-write with atomic operations (`UPDATE SET value = value + 1`), add `SELECT FOR UPDATE`, add `WHERE` clause guards on status transitions, add optimistic concurrency checks. Write migration files for new constraints (don't run them).
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Phase 3: Distributed Cache Race Conditions
|
|
59
|
-
|
|
60
|
-
**Step 1: Inventory all cache interactions**
|
|
61
|
-
For every cache layer (Redis, Memcached, in-memory, CDN, HTTP cache): What data is cached? Key structure? TTL? Where read, written, invalidated? Cache strategy (read-through, write-through, write-behind, cache-aside)?
|
|
62
|
-
|
|
63
|
-
**Step 2: Stale read races**
|
|
64
|
-
For every cached value, trace what happens when underlying data changes:
|
|
65
|
-
- Is cache invalidated on every write path? (Watch for new endpoints that modify data cached by older endpoints.)
|
|
66
|
-
- Invalidation ordering: after successful DB write, not before.
|
|
67
|
-
- Race window: Thread A updates DB → Thread B reads cache (stale hit) → Thread A invalidates. Thread B now has stale data.
|
|
68
|
-
- For dangerous stale data (permissions, balances, inventory): is there a cache bypass mechanism?
|
|
69
|
-
- Impact assessment: how long could stale data persist (TTL = worst case)? What's the consequence?
|
|
70
|
-
|
|
71
|
-
**Step 3: Cache stampede (thundering herd)**
|
|
72
|
-
When a popular key expires, many concurrent requests hit the DB simultaneously. Look for: high-read-rate keys with short TTLs, invalidation on popular keys without stampede protection, existing mitigations (cache locks, stale-while-revalidate, probabilistic early expiration).
|
|
73
|
-
|
|
74
|
-
**Step 4: Read-compute-write cache races**
|
|
75
|
-
Cache-layer read-modify-write: counter increments, incremental aggregation updates, list appends in cache. For each: can it use atomic cache commands (Redis `INCR`, `LPUSH`, `SADD`)? If not, is there locking?
|
|
76
|
-
|
|
77
|
-
**Step 5: Cache-database consistency divergence**
|
|
78
|
-
Look for: delete-then-cache races (stale "not found" cached between DB delete and cache delete), double-write inconsistency (cache write fails silently after DB write), cold-cache stampede on deploy, cross-service cache invalidation gaps.
|
|
79
|
-
|
|
80
|
-
**Step 6: Fix safe cache issues**
|
|
81
|
-
Replace read-compute-write with atomic operations, add missing cache invalidation to write paths, fix invalidation ordering. Document complex issues (stampede protection, distributed consistency) without implementing.
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Phase 4: Queue & Job Idempotency
|
|
86
|
-
|
|
87
|
-
**Step 1: Assess idempotency**
|
|
88
|
-
For every background job/message consumer: What happens if it runs twice? Is there deduplication (idempotency key, unique constraint, "already processed" check)? Can parallel instances of the same job type interfere? What about out-of-order execution?
|
|
89
|
-
|
|
90
|
-
**Step 2: Distributed concurrency**
|
|
91
|
-
Operations assuming single-instance execution? Scheduled jobs running on every instance? Missing distributed locks? Missing leader election?
|
|
92
|
-
|
|
93
|
-
**Step 3: Fix safe issues**
|
|
94
|
-
Add idempotency keys, unique constraints to prevent double-creation, "already processed" guards.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Phase 5: Frontend Concurrency
|
|
99
|
-
|
|
100
|
-
**Step 1: Find user-facing race conditions**
|
|
101
|
-
Double submission (no button disable/request dedup), stale data actions (acting on changed/deleted resources), optimistic UI without proper rollback on failure, concurrent editing without conflict detection, out-of-order API responses overwriting newer data.
|
|
102
|
-
|
|
103
|
-
**Step 2: Fix safe issues**
|
|
104
|
-
Add button disable-on-submit, request debouncing, optimistic UI rollback.
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## Phase 6: Concurrency Test Generation
|
|
109
|
-
|
|
110
|
-
**Step 1: Tests for critical race conditions**
|
|
111
|
-
Simulate concurrent execution for the most dangerous database and cache races. Use parallel test runners, un-awaited async operations, dual-connection transaction tests, cache invalidation timing tests. Mark failing tests as skipped: `// RACE CONDITION: [description]`.
|
|
112
|
-
|
|
113
|
-
**Step 2: Tests for idempotency**
|
|
114
|
-
Call each protected endpoint/job twice with the same input. Verify single side effect and appropriate second-call response.
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## Output
|
|
119
|
-
|
|
120
|
-
Save as `audit-reports/21_RACE_CONDITION_REPORT_[run-number]_[date]_[time in user's local time].md`. Increment run number based on existing reports.
|
|
121
|
-
|
|
122
|
-
### Report Structure
|
|
123
|
-
|
|
124
|
-
1. **Executive Summary** — Safety level (dangerous/risky/moderate/safe/robust), race conditions by severity, "at 100 concurrent requests, these things WILL go wrong: [list]"
|
|
125
|
-
|
|
126
|
-
2. **Shared Mutable State** — Global/module mutable state: | Location | Data | Read By | Written By | Risk | Fix |. Request-scoped leaks. Fixes applied.
|
|
127
|
-
|
|
128
|
-
3. **Database Race Conditions** — Read-modify-write races: | Location | Operation | Current Protection | Risk | Recommendation |. Check-then-act races. Transaction scope issues. Fixes applied with before/after. Migration files created.
|
|
129
|
-
|
|
130
|
-
4. **Cache Race Conditions** — Cache inventory: | Cached Data | Backend | TTL | Read/Write/Invalidation Locations | Consistency Risk |. Stale read risks. Stampede risks. Read-compute-write races. Cache-DB consistency issues. Fixes applied.
|
|
131
|
-
|
|
132
|
-
5. **Queue & Job Idempotency** — | Job/Consumer | Idempotent? | Protection | Risk if Duplicated |. Distributed issues. Fixes applied.
|
|
133
|
-
|
|
134
|
-
6. **Frontend Concurrency** — Double-submission risks. Stale data actions. Optimistic UI issues. Fixes applied.
|
|
135
|
-
|
|
136
|
-
7. **Concurrency Tests Written** — Tests proving race conditions exist (skipped), tests verifying protections, idempotency tests, cache consistency tests.
|
|
137
|
-
|
|
138
|
-
8. **Risk Map** — All race conditions ranked by likelihood × impact. Highest risk first with remediation steps. Estimated manifestation frequency under normal load. Distinguish visible errors vs. silent wrong answers (stale data, lost updates) — silent ones are more dangerous.
|
|
139
|
-
|
|
140
|
-
9. **Recommendations** — Immediate fixes, patterns for new code (optimistic locking, idempotency keys, atomic operations, cache consistency patterns, stampede mitigation), infrastructure to consider, monitoring to add, load testing approach.
|
|
141
|
-
|
|
142
|
-
## Chat Output Requirement
|
|
143
|
-
|
|
144
|
-
In addition to writing the full report file, you MUST print a summary directly in the conversation when you finish. Do not make the user open the report to get the highlights. The chat summary should include:
|
|
145
|
-
|
|
146
|
-
### 1. Status Line
|
|
147
|
-
One sentence: what you did, how long it took, and whether all tests still pass.
|
|
148
|
-
|
|
149
|
-
### 2. Key Findings
|
|
150
|
-
The most important things discovered — bugs, risks, wins, or surprises. Each bullet should be specific and actionable, not vague. Lead with severity or impact.
|
|
151
|
-
|
|
152
|
-
**Good:** "CRITICAL: No backup configuration found for the primary Postgres database — total data loss risk."
|
|
153
|
-
**Bad:** "Found some issues with backups."
|
|
154
|
-
|
|
155
|
-
### 3. Changes Made (if applicable)
|
|
156
|
-
Bullet list of what was actually modified, added, or removed. Skip this section for read-only analysis runs.
|
|
157
|
-
|
|
158
|
-
### 4. Recommendations
|
|
159
|
-
|
|
160
|
-
If there are legitimately beneficial recommendations worth pursuing right now, present them in a table. Do **not** force recommendations — if the audit surfaced no actionable improvements, simply state that no recommendations are warranted at this time and move on.
|
|
161
|
-
|
|
162
|
-
When recommendations exist, use this table format:
|
|
163
|
-
|
|
164
|
-
| # | Recommendation | Impact | Risk if Ignored | Worth Doing? | Details |
|
|
165
|
-
|---|---|---|---|---|---|
|
|
166
|
-
| *Sequential number* | *Short description (≤10 words)* | *What improves if addressed* | *Low / Medium / High / Critical* | *Yes / Probably / Only if time allows* | *1–3 sentences explaining the reasoning, context, or implementation guidance* |
|
|
167
|
-
|
|
168
|
-
Order rows by risk descending (Critical → High → Medium → Low). Be honest in the "Worth Doing?" column — not everything flagged is worth the engineering time. If a recommendation is marginal, say so.
|
|
169
|
-
|
|
170
|
-
### 5. Report Location
|
|
171
|
-
State the full path to the detailed report file for deeper review.
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
**Formatting rules for chat output:**
|
|
176
|
-
- Use markdown headers, bold for severity labels, and bullet points for scannability.
|
|
177
|
-
- Do not duplicate the full report contents — just the highlights and recommendations.
|
|
178
|
-
- If you made zero findings in a phase, say so in one line rather than omitting it silently.
|
|
1
|
+
# Concurrency & Race Condition Audit
|
|
2
|
+
|
|
3
|
+
You are running an overnight concurrency and race condition audit. Your job: find where simultaneous operations cause data corruption, lost updates, double-processing, or inconsistent state.
|
|
4
|
+
|
|
5
|
+
This is primarily analysis and documentation. Race conditions are dangerous to "fix" without deep understanding — fix only clear-cut cases, document everything else with specific, actionable recommendations.
|
|
6
|
+
|
|
7
|
+
Work on branch `concurrency-audit-[date]`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Global Rules
|
|
12
|
+
|
|
13
|
+
- Run tests after every change. Commit format: `fix: [concurrency protection type] in [module]`
|
|
14
|
+
- **Only fix** race conditions where the fix is clearly correct and low-risk: adding unique constraints (migration file, not run), replacing read-modify-write with atomic operations, adding `SELECT FOR UPDATE` to existing transactions, adding `WHERE` clause guards to status transitions, replacing read-compute-write cache patterns with atomic cache operations, adding missing cache invalidation to write paths, fixing invalidation ordering, adding button disable-on-submit.
|
|
15
|
+
- **Do NOT implement** overnight: distributed locking, leader election, event sourcing, global transaction isolation level changes, cache stampede protection (unless project already has a pattern), or TTL changes (unless clearly a framework default).
|
|
16
|
+
- When documenting a race condition, show the **interleaved timeline** — the specific sequence of events that causes the problem, with entity IDs and timing where relevant.
|
|
17
|
+
- Bad: "There's a race condition in the order system"
|
|
18
|
+
- Good: "In `orders_service.js:142`, two concurrent requests can both read `inventory_count=1`, both pass the `>0` check, and both decrement → `inventory_count=-1`. Fix: `SELECT FOR UPDATE` on the inventory row."
|
|
19
|
+
- For cache races, include timing windows: "DB write takes ~50ms, invalidation 10ms after → 60ms stale read window."
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Phase 1: Shared Mutable State Analysis
|
|
24
|
+
|
|
25
|
+
**Step 1: Find global and module-level mutable state**
|
|
26
|
+
Search for: global variables modified after init, module-level variables written during request handling, singletons with mutable properties, static variables that change at runtime, in-memory caches/registries read AND written during requests, module-level connection pools/rate limiters/counters.
|
|
27
|
+
|
|
28
|
+
For each: What data? Which code paths read/write it? Can two requests access it simultaneously? Consequence? (Stale read, lost update, corruption, crash?)
|
|
29
|
+
|
|
30
|
+
**Step 2: Find request-scoped state leaks**
|
|
31
|
+
Request data stored on shared objects, improperly isolated thread-local/async-context storage, middleware modifying shared state per-request, object pools retaining previous request state.
|
|
32
|
+
|
|
33
|
+
**Step 3: Fix clear-cut issues**
|
|
34
|
+
Convert mutable globals to request-scoped state where obvious. Add isolation. Make immutable what doesn't need to mutate. Document complex cases in the report.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Phase 2: Database Race Conditions
|
|
39
|
+
|
|
40
|
+
**Step 1: Find read-modify-write patterns**
|
|
41
|
+
Code that reads a value, modifies it in application code, writes it back — counter increments, availability checks + reservation, balance updates, status transitions, list appends.
|
|
42
|
+
|
|
43
|
+
For each: Is it in a transaction? Appropriate isolation level? Optimistic concurrency (version/`updated_at`)? Pessimistic lock (`SELECT FOR UPDATE`)? What happens with two simultaneous requests right now?
|
|
44
|
+
|
|
45
|
+
**Step 2: Find check-then-act patterns**
|
|
46
|
+
Code that checks a condition then acts on it without concurrency protection — uniqueness checks without unique constraints, availability checks without locks, eligibility checks without guards.
|
|
47
|
+
|
|
48
|
+
For each: Is there a database constraint backing the check? A lock? Or just unprotected application logic?
|
|
49
|
+
|
|
50
|
+
**Step 3: Find transaction scope issues**
|
|
51
|
+
Transactions too narrow (partial protection), too broad (locks held during external API calls), external side effects inside transactions (HTTP calls, queue publishes that can't roll back), nested transaction behavior misunderstandings, missing transactions on multi-statement operations.
|
|
52
|
+
|
|
53
|
+
**Step 4: Fix safe issues**
|
|
54
|
+
Add unique constraints, replace read-modify-write with atomic operations (`UPDATE SET value = value + 1`), add `SELECT FOR UPDATE`, add `WHERE` clause guards on status transitions, add optimistic concurrency checks. Write migration files for new constraints (don't run them).
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Phase 3: Distributed Cache Race Conditions
|
|
59
|
+
|
|
60
|
+
**Step 1: Inventory all cache interactions**
|
|
61
|
+
For every cache layer (Redis, Memcached, in-memory, CDN, HTTP cache): What data is cached? Key structure? TTL? Where read, written, invalidated? Cache strategy (read-through, write-through, write-behind, cache-aside)?
|
|
62
|
+
|
|
63
|
+
**Step 2: Stale read races**
|
|
64
|
+
For every cached value, trace what happens when underlying data changes:
|
|
65
|
+
- Is cache invalidated on every write path? (Watch for new endpoints that modify data cached by older endpoints.)
|
|
66
|
+
- Invalidation ordering: after successful DB write, not before.
|
|
67
|
+
- Race window: Thread A updates DB → Thread B reads cache (stale hit) → Thread A invalidates. Thread B now has stale data.
|
|
68
|
+
- For dangerous stale data (permissions, balances, inventory): is there a cache bypass mechanism?
|
|
69
|
+
- Impact assessment: how long could stale data persist (TTL = worst case)? What's the consequence?
|
|
70
|
+
|
|
71
|
+
**Step 3: Cache stampede (thundering herd)**
|
|
72
|
+
When a popular key expires, many concurrent requests hit the DB simultaneously. Look for: high-read-rate keys with short TTLs, invalidation on popular keys without stampede protection, existing mitigations (cache locks, stale-while-revalidate, probabilistic early expiration).
|
|
73
|
+
|
|
74
|
+
**Step 4: Read-compute-write cache races**
|
|
75
|
+
Cache-layer read-modify-write: counter increments, incremental aggregation updates, list appends in cache. For each: can it use atomic cache commands (Redis `INCR`, `LPUSH`, `SADD`)? If not, is there locking?
|
|
76
|
+
|
|
77
|
+
**Step 5: Cache-database consistency divergence**
|
|
78
|
+
Look for: delete-then-cache races (stale "not found" cached between DB delete and cache delete), double-write inconsistency (cache write fails silently after DB write), cold-cache stampede on deploy, cross-service cache invalidation gaps.
|
|
79
|
+
|
|
80
|
+
**Step 6: Fix safe cache issues**
|
|
81
|
+
Replace read-compute-write with atomic operations, add missing cache invalidation to write paths, fix invalidation ordering. Document complex issues (stampede protection, distributed consistency) without implementing.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Phase 4: Queue & Job Idempotency
|
|
86
|
+
|
|
87
|
+
**Step 1: Assess idempotency**
|
|
88
|
+
For every background job/message consumer: What happens if it runs twice? Is there deduplication (idempotency key, unique constraint, "already processed" check)? Can parallel instances of the same job type interfere? What about out-of-order execution?
|
|
89
|
+
|
|
90
|
+
**Step 2: Distributed concurrency**
|
|
91
|
+
Operations assuming single-instance execution? Scheduled jobs running on every instance? Missing distributed locks? Missing leader election?
|
|
92
|
+
|
|
93
|
+
**Step 3: Fix safe issues**
|
|
94
|
+
Add idempotency keys, unique constraints to prevent double-creation, "already processed" guards.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Phase 5: Frontend Concurrency
|
|
99
|
+
|
|
100
|
+
**Step 1: Find user-facing race conditions**
|
|
101
|
+
Double submission (no button disable/request dedup), stale data actions (acting on changed/deleted resources), optimistic UI without proper rollback on failure, concurrent editing without conflict detection, out-of-order API responses overwriting newer data.
|
|
102
|
+
|
|
103
|
+
**Step 2: Fix safe issues**
|
|
104
|
+
Add button disable-on-submit, request debouncing, optimistic UI rollback.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Phase 6: Concurrency Test Generation
|
|
109
|
+
|
|
110
|
+
**Step 1: Tests for critical race conditions**
|
|
111
|
+
Simulate concurrent execution for the most dangerous database and cache races. Use parallel test runners, un-awaited async operations, dual-connection transaction tests, cache invalidation timing tests. Mark failing tests as skipped: `// RACE CONDITION: [description]`.
|
|
112
|
+
|
|
113
|
+
**Step 2: Tests for idempotency**
|
|
114
|
+
Call each protected endpoint/job twice with the same input. Verify single side effect and appropriate second-call response.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Output
|
|
119
|
+
|
|
120
|
+
Save as `audit-reports/21_RACE_CONDITION_REPORT_[run-number]_[date]_[time in user's local time].md`. Increment run number based on existing reports.
|
|
121
|
+
|
|
122
|
+
### Report Structure
|
|
123
|
+
|
|
124
|
+
1. **Executive Summary** — Safety level (dangerous/risky/moderate/safe/robust), race conditions by severity, "at 100 concurrent requests, these things WILL go wrong: [list]"
|
|
125
|
+
|
|
126
|
+
2. **Shared Mutable State** — Global/module mutable state: | Location | Data | Read By | Written By | Risk | Fix |. Request-scoped leaks. Fixes applied.
|
|
127
|
+
|
|
128
|
+
3. **Database Race Conditions** — Read-modify-write races: | Location | Operation | Current Protection | Risk | Recommendation |. Check-then-act races. Transaction scope issues. Fixes applied with before/after. Migration files created.
|
|
129
|
+
|
|
130
|
+
4. **Cache Race Conditions** — Cache inventory: | Cached Data | Backend | TTL | Read/Write/Invalidation Locations | Consistency Risk |. Stale read risks. Stampede risks. Read-compute-write races. Cache-DB consistency issues. Fixes applied.
|
|
131
|
+
|
|
132
|
+
5. **Queue & Job Idempotency** — | Job/Consumer | Idempotent? | Protection | Risk if Duplicated |. Distributed issues. Fixes applied.
|
|
133
|
+
|
|
134
|
+
6. **Frontend Concurrency** — Double-submission risks. Stale data actions. Optimistic UI issues. Fixes applied.
|
|
135
|
+
|
|
136
|
+
7. **Concurrency Tests Written** — Tests proving race conditions exist (skipped), tests verifying protections, idempotency tests, cache consistency tests.
|
|
137
|
+
|
|
138
|
+
8. **Risk Map** — All race conditions ranked by likelihood × impact. Highest risk first with remediation steps. Estimated manifestation frequency under normal load. Distinguish visible errors vs. silent wrong answers (stale data, lost updates) — silent ones are more dangerous.
|
|
139
|
+
|
|
140
|
+
9. **Recommendations** — Immediate fixes, patterns for new code (optimistic locking, idempotency keys, atomic operations, cache consistency patterns, stampede mitigation), infrastructure to consider, monitoring to add, load testing approach.
|
|
141
|
+
|
|
142
|
+
## Chat Output Requirement
|
|
143
|
+
|
|
144
|
+
In addition to writing the full report file, you MUST print a summary directly in the conversation when you finish. Do not make the user open the report to get the highlights. The chat summary should include:
|
|
145
|
+
|
|
146
|
+
### 1. Status Line
|
|
147
|
+
One sentence: what you did, how long it took, and whether all tests still pass.
|
|
148
|
+
|
|
149
|
+
### 2. Key Findings
|
|
150
|
+
The most important things discovered — bugs, risks, wins, or surprises. Each bullet should be specific and actionable, not vague. Lead with severity or impact.
|
|
151
|
+
|
|
152
|
+
**Good:** "CRITICAL: No backup configuration found for the primary Postgres database — total data loss risk."
|
|
153
|
+
**Bad:** "Found some issues with backups."
|
|
154
|
+
|
|
155
|
+
### 3. Changes Made (if applicable)
|
|
156
|
+
Bullet list of what was actually modified, added, or removed. Skip this section for read-only analysis runs.
|
|
157
|
+
|
|
158
|
+
### 4. Recommendations
|
|
159
|
+
|
|
160
|
+
If there are legitimately beneficial recommendations worth pursuing right now, present them in a table. Do **not** force recommendations — if the audit surfaced no actionable improvements, simply state that no recommendations are warranted at this time and move on.
|
|
161
|
+
|
|
162
|
+
When recommendations exist, use this table format:
|
|
163
|
+
|
|
164
|
+
| # | Recommendation | Impact | Risk if Ignored | Worth Doing? | Details |
|
|
165
|
+
|---|---|---|---|---|---|
|
|
166
|
+
| *Sequential number* | *Short description (≤10 words)* | *What improves if addressed* | *Low / Medium / High / Critical* | *Yes / Probably / Only if time allows* | *1–3 sentences explaining the reasoning, context, or implementation guidance* |
|
|
167
|
+
|
|
168
|
+
Order rows by risk descending (Critical → High → Medium → Low). Be honest in the "Worth Doing?" column — not everything flagged is worth the engineering time. If a recommendation is marginal, say so.
|
|
169
|
+
|
|
170
|
+
### 5. Report Location
|
|
171
|
+
State the full path to the detailed report file for deeper review.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
**Formatting rules for chat output:**
|
|
176
|
+
- Use markdown headers, bold for severity labels, and bullet points for scannability.
|
|
177
|
+
- Do not duplicate the full report contents — just the highlights and recommendations.
|
|
178
|
+
- If you made zero findings in a phase, say so in one line rather than omitting it silently.
|