mustflow 2.113.0 → 2.114.5

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.
@@ -2,7 +2,7 @@
2
2
  mustflow_doc: skill.quadratic-scan-review
3
3
  locale: en
4
4
  canonical: true
5
- revision: 2
5
+ revision: 4
6
6
  lifecycle: mustflow-owned
7
7
  authority: procedure
8
8
  name: quadratic-scan-review
@@ -53,7 +53,7 @@ The review question is not "is there a loop inside a loop?" That catches only th
53
53
  ## Required Inputs
54
54
 
55
55
  - Outer work: the loop, mapper, reducer, render, resolver, batch, import, export, queue consumer, tree builder, graph traversal, or helper call site that repeats.
56
- - Inner work: the scan, membership check, lookup, sort, clone, string copy, JSON serialization, DB query, resolver call, or helper body run for each item.
56
+ - Inner work: the scan, membership check, lookup, sort comparator, clone, string copy, JSON serialization, DB query, resolver call, or helper body run for each item.
57
57
  - Data shape: which collections grow, whether they are user-generated or fixed configuration, maximum known size, duplicate behavior, order requirements, and key fields.
58
58
  - Join or membership key: ID, composite key, normalized key, parent ID, foreign key, timestamp bucket, interval boundary, permission key, tag key, or object identity.
59
59
  - Current semantic contract: order, duplicates, first or last winner, stable tie-breakers, missing records, authorization filtering, stale data, and partial failure.
@@ -78,6 +78,7 @@ The review question is not "is there a loop inside a loop?" That catches only th
78
78
  - Add small tests or fixtures that preserve order, duplicate handling, first or last winner behavior, missing IDs, and composite-key behavior when changing lookup structure.
79
79
  - Add bounded static-review notes or complexity comments only when the code would otherwise look misleading.
80
80
  - Do not add caches when an index built from already-loaded data is enough.
81
+ - Do not claim `Set` or `Map` is guaranteed O(1) or always faster than an array. Use them when repeated lookup count, key dynamics, and data size justify the index setup and memory cost.
81
82
  - Do not replace arrays with maps or sets when duplicates, order, stable tie-breakers, or small hard-capped lists make the array behavior intentional.
82
83
 
83
84
  <!-- mustflow-section: procedure -->
@@ -85,34 +86,36 @@ The review question is not "is there a loop inside a loop?" That catches only th
85
86
 
86
87
  1. Name the repeated path and multiply call count by inner scan length. Review the product `outer_count * inner_count`, not the apparent number of loops.
87
88
  2. Search for the obvious collection-combinator shapes: `map` plus `filter`, `map` plus `find`, `forEach` plus `includes`, `filter` plus `indexOf`, `filter` plus `findIndex`, `reduce` plus spread, and chained `filter().map().sort()` inside a repeated path.
88
- 3. Search for membership checks over arrays. `includes`, `indexOf`, `contains`, `find`, `some`, and list membership inside a loop usually want `Set.has` or `Map.has` unless the searched list is tiny and hard-capped.
89
+ - Treat helper-hidden `find`, `includes`, `some`, `filter`, `indexOf`, or membership checks as the same problem even when the outer call site only says `getStatus`, `hasPermission`, `resolveOwner`, or `renderRow`.
90
+ 3. Search for membership checks over arrays. `includes`, `indexOf`, `contains`, `find`, `some`, and list membership inside a loop usually want `Set.has` or `Map.has` unless the searched list is tiny and hard-capped. In JavaScript, frame this as "avoid repeated linear scans" rather than "Set is guaranteed O(1)"; keyed collections are average sublinear and still have setup, hashing, equality, memory, and resize costs.
89
91
  4. Search for code joins by ID. `posts.map(post => users.find(...))`, `users.map(user => orders.filter(...))`, permission lookups, likes, bookmarks, read state, tags, and relation lists usually need a `Map` or grouped `Map` keyed by ID or composite key.
90
92
  5. Check duplicate removal. `filter((x, i) => arr.indexOf(x) === i)` is O(N^2). Prefer `Set` for scalar values and `Map` keyed by stable identity for objects.
91
93
  6. Check sorted arrays. Sorting does not make `find` fast. If code repeatedly searches a sorted array, use a prebuilt map, binary search with a proven comparator, or a single sorted merge.
92
- 7. Check repeated sorting. Sorting inside a per-item loop is usually worse than scanning once, keeping a top candidate, using a heap, or sorting once before the loop.
93
- 8. Check queue and deletion patterns. JavaScript `shift()` in a large BFS or queue loop moves the remaining array repeatedly; use a head index or real queue. `findIndex` plus `splice` while matching requests to available items can scan and move the same growing array repeatedly; bucket by key and advance a consumption pointer instead.
94
- 9. Check copy-accumulation patterns. `reduce` with `[...acc, item]`, repeated object spread over a growing object, repeated string `+=`, repeated `concat`, and repeated array spread over a growing result can become quadratic copy work. Prefer push, builders, buffers, or one final copy at the boundary.
95
- 10. Check JSON and serialization comparisons. Repeated `JSON.stringify` inside search, equality, sort, dedupe, or render logic multiplies object size by item count. Use explicit keys and precomputed normalized keys.
96
- 11. Open helper bodies called from loops or render paths. Harmless helper names can hide full-list scans, database calls, resolver calls, serialization, sorting, or permission checks.
97
- 12. Check ORM and lazy relations. A single visible loop can become one query per entity. Replace per-entity relation access with eager loading, joins, `WHERE id IN (...)`, batch loading, or DataLoader-style batching.
98
- 13. Check GraphQL and nested resolvers. Parent-list resolvers plus per-field DB or API calls create hidden pairwise fan-out. Batch by parent IDs and preserve field-level authorization semantics.
99
- 14. Check render-time lookup. `rows.map(row => columns.find(...))`, `items.map(item => selectedIds.includes(item.id))`, derived data recomputed on every render, and per-row helper scans should move to memoized sets or maps when inputs are large or stable.
100
- 15. Check all-data-in-app joins. Fetching `allUsers`, `allOrders`, or `allLogs` and joining in application arrays is often a database join without an index. Push join, filter, sort, and pagination to the data store when the data store owns the index and semantics allow it.
101
- 16. Check tree and graph construction. `nodes.map(node => nodes.filter(child => child.parentId === node.id))` should usually become `childrenByParentId` plus one assembly pass. `visited.includes(id)` in traversal should be a `Set`. Very deep trees may also need an explicit stack to avoid call-stack failure.
102
- 17. Check event-log and time-window scans. Repeatedly scanning all previous events per event should usually become grouping, sorting once, and one pointer or rolling aggregate per key.
103
- 18. Check interval overlap. All-pairs range checks are sometimes necessary, but overlap detection often only needs sorting by start and comparing adjacent or active intervals.
104
- 19. Check true all-pairs similarity separately. If every item must be compared with every other item, do not promise a linear rewrite. First narrow candidates with stable keys, categories, buckets, hashes, n-grams, ranges, or database indexes, then compare only within the candidate set.
105
- 20. Check incremental updates. Adding one item should not recompute a full ranking, group map, unread count, cart total, or dashboard aggregate unless the collection is fixed and tiny.
106
- 21. Separate index from cache. A `Map` built from current input is an index. A cache stores results across calls or time. Use an index for repeated lookup over already-owned data before introducing cache invalidation.
107
- 22. Require a hard cap for "small list" exceptions. Countries, enum options, or fixed config lists may stay arrays if the cap is real. User data, logs, orders, comments, permissions, tags, events, and uploaded rows need scalable lookup.
108
- 23. Preserve behavior while changing shape. Before replacing scans with indexes, state how order, duplicates, first or last match, missing references, authorization filtering, and stable keys are preserved.
109
- 24. Add growth evidence when feasible. If configured tests or fixtures can scale input size, prefer a small growth test that compares behavior at larger counts. If benchmarking is not configured, report complexity-only evidence instead of a speedup claim.
94
+ 7. Check repeated sorting. Sorting inside a per-item loop is usually worse than scanning once, keeping a top candidate, using a heap, or sorting once before the loop. Sorting a collection does not make exact lookup cheap; use `Map` for exact key lookup and sorted merge or binary search for range or ordered-window work.
95
+ 8. Check expensive sort comparators. A comparator that parses dates, calls `localeCompare` with options, normalizes strings, computes scores, reads files, serializes JSON, or builds lookup keys may run many times per item. Precompute keys with decorate-sort-undecorate or store the normalized key before sorting.
96
+ 9. Check queue and deletion patterns. JavaScript `shift()` or `unshift()` in a large BFS or queue loop moves the remaining array repeatedly; use a head index or real queue. `findIndex` plus `splice` while matching requests to available items can scan and move the same growing array repeatedly; bucket by key and advance a consumption pointer instead. If order is irrelevant, swap the item with the last slot and `pop()` instead of repeated middle `splice()`.
97
+ 10. Check copy-accumulation patterns. `reduce` with `[...acc, item]`, repeated object spread over a growing object, repeated string `+=`, repeated `concat`, and repeated array spread over a growing result can become quadratic copy work. Prefer push, builders, buffers, or one final copy at the boundary.
98
+ 11. Check JSON and serialization comparisons. Repeated `JSON.stringify` inside search, equality, sort, dedupe, or render logic multiplies object size by item count. Use explicit keys and precomputed normalized keys.
99
+ 12. Open helper bodies called from loops or render paths. Harmless helper names can hide full-list scans, database calls, resolver calls, serialization, sorting, or permission checks.
100
+ 13. Check ORM and lazy relations. A single visible loop can become one query per entity. Replace per-entity relation access with eager loading, joins, `WHERE id IN (...)`, batch loading, or DataLoader-style batching.
101
+ 14. Check GraphQL and nested resolvers. Parent-list resolvers plus per-field DB or API calls create hidden pairwise fan-out. Batch by parent IDs and preserve field-level authorization semantics.
102
+ 15. Check render-time lookup. `rows.map(row => columns.find(...))`, `items.map(item => selectedIds.includes(item.id))`, derived data recomputed on every render, and per-row helper scans should move to memoized sets or maps when inputs are large or stable.
103
+ 16. Check all-data-in-app joins. Fetching `allUsers`, `allOrders`, or `allLogs` and joining in application arrays is often a database join without an index. Push join, filter, sort, and pagination to the data store when the data store owns the index and semantics allow it.
104
+ 17. Check tree and graph construction. `nodes.map(node => nodes.filter(child => child.parentId === node.id))` should usually become `childrenByParentId` plus one assembly pass. `visited.includes(id)` in traversal should be a `Set`. Very deep trees may also need an explicit stack to avoid call-stack failure.
105
+ 18. Check event-log and time-window scans. Repeatedly scanning all previous events per event should usually become grouping, sorting once, and one pointer or rolling aggregate per key.
106
+ 19. Check interval overlap. All-pairs range checks are sometimes necessary, but overlap detection often only needs sorting by start and comparing adjacent or active intervals.
107
+ 20. Check true all-pairs similarity separately. If every item must be compared with every other item, do not promise a linear rewrite. First narrow candidates with stable keys, categories, buckets, hashes, n-grams, ranges, or database indexes, then compare only within the candidate set.
108
+ 21. Check incremental updates. Adding one item should not recompute a full ranking, group map, unread count, cart total, or dashboard aggregate unless the collection is fixed and tiny.
109
+ 22. Separate index from cache. A `Map` built from current input is an index. A cache stores results across calls or time. Use an index for repeated lookup over already-owned data before introducing cache invalidation.
110
+ 23. Require a hard cap for "small list" exceptions. Countries, enum options, or fixed config lists may stay arrays if the cap is real. User data, logs, orders, comments, permissions, tags, events, and uploaded rows need scalable lookup.
111
+ 24. Preserve behavior while changing shape. Before replacing scans with indexes, state how order, duplicates, first or last match, missing references, authorization filtering, and stable keys are preserved.
112
+ 25. Add growth evidence when feasible. If configured tests or fixtures can scale input size, prefer a small growth test that compares behavior at larger counts. If benchmarking is not configured, report complexity-only evidence instead of a speedup claim.
110
113
 
111
114
  <!-- mustflow-section: postconditions -->
112
115
  ## Postconditions
113
116
 
114
117
  - Each suspected O(N^2) path has an outer count, inner count, and data-growth classification.
115
- - Repeated membership checks, code joins, duplicate removal, tree building, resolver fan-out, render-time lookup, helper-hidden scans, repeated sort, queue `shift()`, `findIndex` plus `splice`, copy accumulation, interval scans, all-pairs candidate narrowing, and JSON comparison are fixed or reported.
118
+ - Repeated membership checks, code joins, duplicate removal, tree building, resolver fan-out, render-time lookup, helper-hidden scans, repeated sort, expensive comparators, queue `shift()` or `unshift()`, `findIndex` plus `splice`, copy accumulation, interval scans, all-pairs candidate narrowing, and JSON comparison are fixed or reported.
116
119
  - Array-to-set or array-to-map changes preserve order, duplicates, missing records, first or last winner, authorization, and stable key behavior.
117
120
  - Small-list exceptions have an explicit hard cap or are reported as residual risk.
118
121
  - Performance claims are backed by configured evidence or labeled as static complexity risk.
@@ -2,7 +2,7 @@
2
2
  mustflow_doc: skill.web-render-performance-review
3
3
  locale: en
4
4
  canonical: true
5
- revision: 1
5
+ revision: 2
6
6
  lifecycle: mustflow-owned
7
7
  authority: procedure
8
8
  name: web-render-performance-review
@@ -29,7 +29,7 @@ metadata:
29
29
  <!-- mustflow-section: purpose -->
30
30
  ## Purpose
31
31
 
32
- Review web first-render performance as a critical rendering path problem: the browser must discover the first viewport HTML, CSS, data, fonts, scripts, and LCP media early, while noncritical work stays out of the way.
32
+ Review web first-render performance as a critical rendering path problem: the browser must discover the first viewport HTML, CSS, data, fonts, scripts, and LCP media early, while noncritical work stays out of the way. Treat initial JavaScript as main-thread work, not just transfer bytes.
33
33
 
34
34
  The review question is not "did we compress assets?" It is "what blocks the first useful pixels, what competes with the LCP resource, what shifts layout later, and what work runs on the main thread before the user can see or use the page?"
35
35
 
@@ -59,7 +59,7 @@ The review question is not "did we compress assets?" It is "what blocks the firs
59
59
  - Font loading ledger: font files, weights, subsets, `unicode-range`, format, preload list, `font-display`, fallback metrics, Korean or CJK coverage, FOIT risk, and CLS risk.
60
60
  - Image, video, and iframe ledger: `srcset`, `sizes`, intrinsic dimensions, `aspect-ratio`, lazy/eager loading, `fetchpriority`, CDN transformation, thumbnails, embeds, ads, maps, and offscreen media.
61
61
  - Third-party script ledger: analytics, tag managers, ads, A/B testing, heatmaps, chat widgets, payment widgets, maps, embeds, consent gates, page scope, and user-intent loading.
62
- - JavaScript bundle and hydration ledger: initial route bundle, client/server boundaries, `use client` placement, dynamic imports, chunk graph, modulepreload, route prefetching, parse/compile/execute cost, and main-thread tasks.
62
+ - JavaScript bundle and hydration ledger: initial route bundle, client/server boundaries, `use client` placement, dynamic imports, chunk graph, modulepreload, route prefetching, gzip or brotli transfer size, decompressed size, parse/compile/evaluate cost, and main-thread tasks.
63
63
  - Data and HTML delivery ledger: first-view data owner, SSR/RSC/loader/static generation, client effects, serialized initial data, streaming shell, Suspense or loading boundaries, personalization holes, and TTFB evidence.
64
64
  - Cache, compression, and resource-hint ledger: CDN HTML cacheability, cache-control headers, fingerprinted assets, private data boundaries, text compression, Early Hints, preconnect origins, and preload accuracy.
65
65
  - Main-thread and long-task ledger: expensive parsing, syntax highlighting, charting, search indexing, markdown rendering, JSON work, layout-heavy below-fold DOM, idle work, worker offload, and chunking strategy.
@@ -103,25 +103,26 @@ The review question is not "did we compress assets?" It is "what blocks the firs
103
103
  16. Keep `use client` boundaries narrow in React and Next.js style apps. A top-level layout or page marked client-side can drag static markup, data, and child components into the hydration and bundle cost.
104
104
  17. Lazy-load heavy interactive widgets. Modals, charts, editors, maps, markdown renderers, syntax highlighters, date pickers, and rarely opened panels should usually enter through dynamic import or route-level loading.
105
105
  18. Split code by "not needed for this route now," not by chunk theater. Too many tiny chunks can add request and module scheduling overhead, while one giant common chunk ships unused code everywhere.
106
- 19. Use `modulepreload` only for critical initial modules. Preloading every possible route, widget, or secondary chunk creates a new waterfall in nicer clothes.
107
- 20. Do not fetch first-view data in a client effect when server, route loader, RSC, static generation, or serialized initial data can safely provide it. Client effects are for enhancement, subscriptions, and browser-only data, not required first pixels.
108
- 21. Stream HTML and shell early. Send stable layout, navigation, critical content, and placeholders as soon as possible; put slow regions behind Suspense, loading boundaries, or progressive sections when the framework supports it.
109
- 22. Split static shells from dynamic holes. Cache and reuse stable HTML around narrow personalized or fast-changing regions instead of making the whole page uncached and origin-bound for one username, cart count, or recommendation slot.
110
- 23. Investigate slow TTFB before polishing the browser side. If TTFB is around or above one second, use Server-Timing, origin logs, cache status, query count, API count, SSR timing, or configured evidence to find the upstream wait.
111
- 24. Cache HTML at the edge when it is safe. Low-personalization pages can often be CDN cached with revalidation or hole punching; private or user-specific pages need explicit cache boundaries to avoid data leaks.
112
- 25. Cache fingerprinted assets with long immutable headers. Do not confuse `no-cache`, `no-store`, `private`, and long-lived immutable caching; the wrong header can either slow every visit or leak user-specific content.
113
- 26. Enable text compression for HTML, CSS, JS, JSON, SVG, and other text resources. Do not waste time recompressing already compressed media such as JPEG, PNG, WebP, AVIF, video, or font formats that are already compressed.
114
- 27. Use Early Hints and preconnect sparingly. They help only when the critical resource or origin is definitely needed soon; speculative hints for many origins can steal sockets and bandwidth from the real first-render path.
115
- 28. Use `content-visibility: auto` with `contain-intrinsic-size` for huge below-fold DOM when supported. It can reduce early layout and paint work, but missing intrinsic size can cause scroll jumps.
116
- 29. Break long main-thread tasks. Heavy JSON parsing, syntax highlighting, chart rendering, markdown rendering, search indexing, diffing, and data formatting may need chunking, idle callbacks, workers, virtualization, or server-side precomputation.
117
- 30. Audit route prefetch behavior. Framework prefetching can help a few likely next clicks, but a page with hundreds of links can turn prefetch into a silent network and CPU tax; disable or move it to hover or viewport intent when needed.
118
- 31. Label evidence honestly. If there is no configured browser trace, network waterfall, bundle report, RUM, or lab measurement, report findings as static critical-path risk or configured-test evidence, not measured Web Vitals improvement.
106
+ 19. Do not report gzip-only JavaScript wins as first-render wins. Check whether initial parse, compile, evaluate, hydration, and long tasks improved for the route; use `client-bundle-pruning-review` when unused initial code, chunk boundaries, barrels, side effects, or vendor chunks are the root cause.
107
+ 20. Use `modulepreload` only for critical initial modules. Preloading every possible route, widget, or secondary chunk creates a new waterfall in nicer clothes. Validate preload, prefetch, and route-prefetch priority with Resource Timing or configured evidence when a claim depends on request order.
108
+ 21. Do not fetch first-view data in a client effect when server, route loader, RSC, static generation, or serialized initial data can safely provide it. Client effects are for enhancement, subscriptions, and browser-only data, not required first pixels.
109
+ 22. Stream HTML and shell early. Send stable layout, navigation, critical content, and placeholders as soon as possible; put slow regions behind Suspense, loading boundaries, or progressive sections when the framework supports it.
110
+ 23. Split static shells from dynamic holes. Cache and reuse stable HTML around narrow personalized or fast-changing regions instead of making the whole page uncached and origin-bound for one username, cart count, or recommendation slot.
111
+ 24. Investigate slow TTFB before polishing the browser side. If TTFB is around or above one second, use Server-Timing, origin logs, cache status, query count, API count, SSR timing, or configured evidence to find the upstream wait.
112
+ 25. Cache HTML at the edge when it is safe. Low-personalization pages can often be CDN cached with revalidation or hole punching; private or user-specific pages need explicit cache boundaries to avoid data leaks.
113
+ 26. Cache fingerprinted assets with long immutable headers. Do not confuse `no-cache`, `no-store`, `private`, and long-lived immutable caching; the wrong header can either slow every visit or leak user-specific content.
114
+ 27. Enable text compression for HTML, CSS, JS, JSON, SVG, and other text resources. Do not waste time recompressing already compressed media such as JPEG, PNG, WebP, AVIF, video, or font formats that are already compressed.
115
+ 28. Use Early Hints and preconnect sparingly. They help only when the critical resource or origin is definitely needed soon; speculative hints for many origins can steal sockets and bandwidth from the real first-render path.
116
+ 29. Use `content-visibility: auto` with `contain-intrinsic-size` for huge below-fold DOM when supported. It can reduce early layout and paint work, but missing intrinsic size can cause scroll jumps.
117
+ 30. Break long main-thread tasks. Heavy JSON parsing, syntax highlighting, chart rendering, markdown rendering, search indexing, diffing, and data formatting may need chunking, idle callbacks, workers, virtualization, or server-side precomputation.
118
+ 31. Audit route prefetch behavior. Framework prefetching can help a few likely next clicks, but a page with hundreds of links can turn prefetch into a silent network and CPU tax; disable or move it to hover or viewport intent when needed.
119
+ 32. Label evidence honestly. If there is no configured browser trace, network waterfall, bundle report, RUM, or lab measurement, report findings as static critical-path risk or configured-test evidence, not measured Web Vitals improvement.
119
120
 
120
121
  <!-- mustflow-section: postconditions -->
121
122
  ## Postconditions
122
123
 
123
124
  - The first viewport, LCP candidate, discovery path, critical CSS, fonts, media, scripts, data, HTML delivery, cache behavior, resource hints, and main-thread work are explicit.
124
- - Lazy LCP media, hidden background hero discovery, priority inflation, render-blocking global CSS, over-preloaded fonts, unsubset Korean or CJK fonts, oversized images, missing dimensions, eager offscreen embeds, global third-party scripts, broad client boundaries, eager heavy widgets, client-effect first data, all-or-nothing HTML waits, unsafe cache headers, hint spam, below-fold layout work, long tasks, and overbroad prefetch are fixed or reported.
125
+ - Lazy LCP media, hidden background hero discovery, priority inflation, render-blocking global CSS, over-preloaded fonts, unsubset Korean or CJK fonts, oversized images, missing dimensions, eager offscreen embeds, global third-party scripts, broad client boundaries, eager heavy widgets, gzip-only JavaScript claims, client-effect first data, all-or-nothing HTML waits, unsafe cache headers, hint spam, below-fold layout work, long tasks, and overbroad prefetch are fixed or reported.
125
126
  - Performance claims are backed by current configured evidence or labeled as static review risk, manual-only measurement, or missing evidence.
126
127
  - Accessibility, layout stability, privacy, security, cache correctness, and framework boundaries remain intact or are reported as tradeoffs.
127
128
 
@@ -1,6 +1,6 @@
1
1
  id = "default"
2
2
  name = "default"
3
- version = "2.113.0"
3
+ version = "2.114.5"
4
4
  description = "Minimal workflow for LLM agents to read, edit, and verify their work in a repository."
5
5
  common_root = "common"
6
6
  locales_root = "locales"