@nklisch/pi-agile-workflow 0.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/.codex-plugin/plugin.json +28 -0
  3. package/CHANGELOG.md +591 -0
  4. package/README.md +107 -0
  5. package/docs/ARCHITECTURE.md +716 -0
  6. package/docs/MIGRATION.md +419 -0
  7. package/docs/PRINCIPLES.md +464 -0
  8. package/docs/ROADMAP.md +95 -0
  9. package/docs/SPEC.md +855 -0
  10. package/docs/VISION.md +106 -0
  11. package/extensions/agile-workflow.test.ts +419 -0
  12. package/extensions/agile-workflow.ts +467 -0
  13. package/hooks/hooks.json +52 -0
  14. package/hooks/scripts/prompt-context.py +628 -0
  15. package/hooks/scripts/substrate-maintainer.py +359 -0
  16. package/hooks/scripts/test_prompt_context.py +757 -0
  17. package/package.json +30 -0
  18. package/scripts/install-work-view.sh +165 -0
  19. package/scripts/tests/agent-metadata.test.sh +75 -0
  20. package/scripts/tests/bump-version.test.sh +552 -0
  21. package/scripts/tests/channel-parity.test.sh +117 -0
  22. package/scripts/tests/convert-content-integrity.test.sh +246 -0
  23. package/scripts/tests/convert-install-routing.test.sh +159 -0
  24. package/scripts/tests/install-work-view.test.sh +411 -0
  25. package/scripts/tests/pi-package-metadata.test.sh +119 -0
  26. package/scripts/tests/work-board-shim.test.sh +239 -0
  27. package/scripts/tests/work-view-dist-version.test.sh +105 -0
  28. package/scripts/work-board.sh +64 -0
  29. package/scripts/work-view.sh +423 -0
  30. package/skills/autopilot/SKILL.md +330 -0
  31. package/skills/autopilot/agents/openai.yaml +6 -0
  32. package/skills/board/SKILL.md +62 -0
  33. package/skills/board/agents/openai.yaml +6 -0
  34. package/skills/bold-refactor/SKILL.md +244 -0
  35. package/skills/bold-refactor/agents/openai.yaml +6 -0
  36. package/skills/bug-scan/SKILL.md +378 -0
  37. package/skills/bug-scan/agents/openai.yaml +6 -0
  38. package/skills/bug-scan/references/async-promises.md +119 -0
  39. package/skills/bug-scan/references/concurrency-races.md +148 -0
  40. package/skills/bug-scan/references/data-layer.md +167 -0
  41. package/skills/bug-scan/references/error-handling.md +197 -0
  42. package/skills/bug-scan/references/gate-item-template.md +94 -0
  43. package/skills/bug-scan/references/language-footguns.md +219 -0
  44. package/skills/bug-scan/references/parked-item-template.md +103 -0
  45. package/skills/bug-scan/references/report-template.md +115 -0
  46. package/skills/bug-scan/references/resource-leaks.md +199 -0
  47. package/skills/bug-scan/references/state-closures.md +148 -0
  48. package/skills/bug-scan/references/time-numbers.md +158 -0
  49. package/skills/convert/SKILL.md +1463 -0
  50. package/skills/convert/agents/openai.yaml +6 -0
  51. package/skills/convert/references/legacy-overlap-migration.md +179 -0
  52. package/skills/deep-code-scan/SKILL.md +378 -0
  53. package/skills/deep-code-scan/agents/openai.yaml +6 -0
  54. package/skills/deep-code-scan/references/artifact-ledger.md +148 -0
  55. package/skills/deep-code-scan/references/consolidation.md +91 -0
  56. package/skills/deep-code-scan/references/decomposition.md +127 -0
  57. package/skills/deep-code-scan/references/item-templates.md +263 -0
  58. package/skills/deep-code-scan/references/lane-catalog.md +129 -0
  59. package/skills/deep-code-scan/references/review-gauntlet.md +108 -0
  60. package/skills/deep-code-scan/references/scanner-brief.md +152 -0
  61. package/skills/e2e-test-design/SKILL.md +517 -0
  62. package/skills/e2e-test-design/references/anti-tautology.md +261 -0
  63. package/skills/e2e-test-design/references/service-mocks.md +234 -0
  64. package/skills/e2e-test-design/references/test-taxonomy.md +211 -0
  65. package/skills/epic-design/SKILL.md +476 -0
  66. package/skills/epicize/SKILL.md +210 -0
  67. package/skills/epicize/agents/openai.yaml +6 -0
  68. package/skills/feature-design/SKILL.md +472 -0
  69. package/skills/fix/SKILL.md +173 -0
  70. package/skills/gate-cruft/SKILL.md +258 -0
  71. package/skills/gate-docs/SKILL.md +278 -0
  72. package/skills/gate-patterns/SKILL.md +389 -0
  73. package/skills/gate-refactor/SKILL.md +408 -0
  74. package/skills/gate-security/SKILL.md +275 -0
  75. package/skills/gate-tests/SKILL.md +367 -0
  76. package/skills/groom/SKILL.md +162 -0
  77. package/skills/groom/agents/openai.yaml +6 -0
  78. package/skills/ideate/SKILL.md +185 -0
  79. package/skills/ideate/agents/openai.yaml +6 -0
  80. package/skills/implement/SKILL.md +288 -0
  81. package/skills/implement-orchestrator/SKILL.md +604 -0
  82. package/skills/park/SKILL.md +111 -0
  83. package/skills/perf-design/SKILL.md +427 -0
  84. package/skills/perf-scout/SKILL.md +404 -0
  85. package/skills/perf-scout/agents/openai.yaml +6 -0
  86. package/skills/perf-scout/references/algorithmic-and-data-structures.md +126 -0
  87. package/skills/perf-scout/references/approximation-and-precomputation.md +136 -0
  88. package/skills/perf-scout/references/caching-and-memoization.md +123 -0
  89. package/skills/perf-scout/references/compiler-runtime-and-language.md +136 -0
  90. package/skills/perf-scout/references/database-and-storage-internals.md +144 -0
  91. package/skills/perf-scout/references/distributed-systems.md +150 -0
  92. package/skills/perf-scout/references/game-engine-and-realtime.md +136 -0
  93. package/skills/perf-scout/references/gpu-and-accelerators.md +130 -0
  94. package/skills/perf-scout/references/idea-ranking.md +75 -0
  95. package/skills/perf-scout/references/io-and-batching.md +135 -0
  96. package/skills/perf-scout/references/memory-and-data-locality.md +137 -0
  97. package/skills/perf-scout/references/parallelism-and-vectorization.md +126 -0
  98. package/skills/perf-scout/references/parked-item-template.md +117 -0
  99. package/skills/perf-scout/references/peer-review-pass.md +150 -0
  100. package/skills/perf-scout/references/report-template.md +148 -0
  101. package/skills/principles/SKILL.md +678 -0
  102. package/skills/principles/references/models.md +191 -0
  103. package/skills/principles/references/subagents.md +158 -0
  104. package/skills/prose-author/SKILL.md +185 -0
  105. package/skills/refactor-conventions-creator/SKILL.md +359 -0
  106. package/skills/refactor-conventions-creator/agents/openai.yaml +6 -0
  107. package/skills/refactor-conventions-creator/references/common-structures.md +91 -0
  108. package/skills/refactor-conventions-creator/references/common-styles.md +90 -0
  109. package/skills/refactor-design/SKILL.md +384 -0
  110. package/skills/release-deploy/SKILL.md +667 -0
  111. package/skills/release-deploy/agents/openai.yaml +6 -0
  112. package/skills/research/SKILL.md +166 -0
  113. package/skills/research/agents/openai.yaml +6 -0
  114. package/skills/review/SKILL.md +267 -0
  115. package/skills/review/references/deep-review.md +98 -0
  116. package/skills/review/references/review-lenses.md +68 -0
  117. package/skills/review/references/substrate-side-effects.md +161 -0
  118. package/skills/review/references/target-resolution.md +52 -0
  119. package/skills/scope/SKILL.md +486 -0
  120. package/work-view/Cargo.lock +486 -0
  121. package/work-view/Cargo.toml +9 -0
  122. package/work-view/crates/cli/.work-view-version +1 -0
  123. package/work-view/crates/cli/Cargo.toml +18 -0
  124. package/work-view/crates/cli/src/actionable.rs +500 -0
  125. package/work-view/crates/cli/src/args.rs +792 -0
  126. package/work-view/crates/cli/src/board/assets/board.css +855 -0
  127. package/work-view/crates/cli/src/board/assets/board.js +259 -0
  128. package/work-view/crates/cli/src/board/assets/card.js +139 -0
  129. package/work-view/crates/cli/src/board/assets/components.css +290 -0
  130. package/work-view/crates/cli/src/board/assets/dependency.js +1193 -0
  131. package/work-view/crates/cli/src/board/assets/detail.js +256 -0
  132. package/work-view/crates/cli/src/board/assets/filters.js +389 -0
  133. package/work-view/crates/cli/src/board/assets/index.html +77 -0
  134. package/work-view/crates/cli/src/board/assets/kanban.js +231 -0
  135. package/work-view/crates/cli/src/board/assets/markdown.js +260 -0
  136. package/work-view/crates/cli/src/board/assets/motion.css +131 -0
  137. package/work-view/crates/cli/src/board/assets/state.js +245 -0
  138. package/work-view/crates/cli/src/board/assets/table.js +304 -0
  139. package/work-view/crates/cli/src/board/assets/tokens.css +602 -0
  140. package/work-view/crates/cli/src/board/assets/views.js +41 -0
  141. package/work-view/crates/cli/src/board/assets.rs +162 -0
  142. package/work-view/crates/cli/src/board/feed.rs +204 -0
  143. package/work-view/crates/cli/src/board/mod.rs +246 -0
  144. package/work-view/crates/cli/src/board/open.rs +144 -0
  145. package/work-view/crates/cli/src/board/server.rs +407 -0
  146. package/work-view/crates/cli/src/main.rs +195 -0
  147. package/work-view/crates/cli/src/render.rs +354 -0
  148. package/work-view/crates/cli/src/scope.rs +157 -0
  149. package/work-view/crates/cli/src/stale.rs +581 -0
  150. package/work-view/crates/cli/tests/board-js/dependency-table.test.mjs +64 -0
  151. package/work-view/crates/cli/tests/board-js/expanded-browsing.test.mjs +79 -0
  152. package/work-view/crates/cli/tests/board-js/harness-smoke.test.mjs +11 -0
  153. package/work-view/crates/cli/tests/board-js/harness.mjs +437 -0
  154. package/work-view/crates/cli/tests/board-js/kanban-detail.test.mjs +75 -0
  155. package/work-view/crates/cli/tests/board-js/markdown-filter.test.mjs +60 -0
  156. package/work-view/crates/cli/tests/fixtures/golden/.work/CONVENTIONS.md +3 -0
  157. package/work-view/crates/cli/tests/fixtures/golden/.work/active/epics/epic-alpha.md +16 -0
  158. package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-a.md +16 -0
  159. package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-b.md +16 -0
  160. package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-alpha-1.md +16 -0
  161. package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-research-1.md +19 -0
  162. package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-done.md +16 -0
  163. package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-shipped.md +18 -0
  164. package/work-view/crates/cli/tests/fixtures/golden/.work/backlog/idea-backlog.md +7 -0
  165. package/work-view/crates/cli/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
  166. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/CONVENTIONS.md +6 -0
  167. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-dep-done.md +17 -0
  168. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-design-ready.md +17 -0
  169. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-impl-ready.md +17 -0
  170. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/stories/story-review-ready.md +17 -0
  171. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/CONVENTIONS.md +4 -0
  172. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/epics/malformed-no-closing-fence.md +8 -0
  173. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/features/good-item.md +16 -0
  174. package/work-view/crates/cli/tests/integration.rs +2833 -0
  175. package/work-view/crates/core/Cargo.toml +13 -0
  176. package/work-view/crates/core/src/error.rs +61 -0
  177. package/work-view/crates/core/src/filter.rs +804 -0
  178. package/work-view/crates/core/src/graph.rs +324 -0
  179. package/work-view/crates/core/src/index.rs +590 -0
  180. package/work-view/crates/core/src/lib.rs +54 -0
  181. package/work-view/crates/core/src/model.rs +202 -0
  182. package/work-view/crates/core/src/parse.rs +494 -0
  183. package/work-view/crates/core/tests/fixtures/golden/.work/CONVENTIONS.md +15 -0
  184. package/work-view/crates/core/tests/fixtures/golden/.work/active/epics/epic-core.md +16 -0
  185. package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-parser.md +16 -0
  186. package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-query.md +16 -0
  187. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/malformed-no-id.md +15 -0
  188. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-parse-unit.md +16 -0
  189. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-security-gate.md +16 -0
  190. package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-old.md +16 -0
  191. package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-parser.md +17 -0
  192. package/work-view/crates/core/tests/fixtures/golden/.work/backlog/idea-future-board.md +7 -0
  193. package/work-view/crates/core/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
  194. package/work-view/crates/core/tests/fixtures/precedence/.work/CONVENTIONS.md +10 -0
  195. package/work-view/crates/core/tests/fixtures/precedence/.work/archive/dup-item.md +18 -0
  196. package/work-view/crates/core/tests/fixtures/precedence/.work/releases/v2.0/dup-item.md +18 -0
  197. package/work-view/crates/core/tests/integration.rs +541 -0
  198. package/work-view/dist/.gitattributes +1 -0
  199. package/work-view/dist/README.md +42 -0
  200. package/work-view/dist/aarch64-apple-darwin/work-view +0 -0
  201. package/work-view/dist/aarch64-unknown-linux-musl/work-view +0 -0
  202. package/work-view/dist/x86_64-apple-darwin/work-view +0 -0
  203. package/work-view/dist/x86_64-unknown-linux-musl/work-view +0 -0
@@ -0,0 +1,135 @@
1
+ # I/O & Batching — Perf-Scout Strategy Lens
2
+
3
+ > **When to load this lens**: DB/network/disk calls, per-item I/O inside loops,
4
+ > serialization, syscalls, N+1 patterns, chatty service boundaries.
5
+ >
6
+ > **Where these ideas come from**: database engines, high-throughput servers, OS
7
+ > kernels (io_uring, zero-copy), and storage systems. I/O is usually thousands of
8
+ > times slower than CPU, so *the number and shape of I/O operations dominates wall
9
+ > time* on most services. Every entry is a *candidate* hypothesis, not a proven
10
+ > win. Cite `file:line`, attribute the source, give a validation path.
11
+
12
+ ## Detection signals (where this lens might apply — not proof)
13
+ - A query/request/read inside a loop (`for row: db.get(row.id)`) — the N+1 shape.
14
+ - Sequential awaits of independent I/O (covered also by the parallelism lens).
15
+ - Row-at-a-time reads/writes against a DB or file.
16
+ - Small frequent syscalls (per-byte/per-line read/write, unbuffered I/O).
17
+ - Large objects serialized to JSON/text on a hot path.
18
+ - Repeated connection setup/teardown; no pooling.
19
+ - Full-payload transfers where a subset of fields is used.
20
+ - Small synchronous request/response round-trips on default sockets (possible Nagle/delayed-ACK stalls).
21
+ - Large file→socket transfers the app never inspects; bulk streaming that pollutes the cache.
22
+
23
+ ## Strategies
24
+
25
+ ### 1. Eliminate N+1 with batch/bulk queries
26
+ - **Borrowed from**: ORM dataloaders, SQL `IN`/joins.
27
+ - **The idea**: replace per-item queries with one bulk query (`WHERE id IN (...)`, a join, or a `dataloader` that coalesces a tick's keys).
28
+ - **Code signals**: a DB/RPC call inside a loop keyed by the loop variable.
29
+ - **Speculative win**: N round-trips collapse to 1; latency drops from N×rtt to 1×rtt.
30
+ - **Cost / risk**: large `IN` lists; result reassembly; query plan changes.
31
+ - **Validate by**: count round-trips; end-to-end latency — perf-design.
32
+
33
+ ### 2. Batch writes
34
+ - **Borrowed from**: bulk inserts, LSM write batching, group commit.
35
+ - **The idea**: accumulate writes and flush as one multi-row insert / pipelined batch / single transaction instead of one statement per item.
36
+ - **Code signals**: `for item: insert(item)` — per-row inserts/updates.
37
+ - **Speculative win**: amortizes round-trip and commit overhead across the batch.
38
+ - **Cost / risk**: partial-failure handling; batch sizing; latency to durability.
39
+ - **Validate by**: write throughput across batch sizes.
40
+
41
+ ### 3. Buffer small I/O
42
+ - **Borrowed from**: stdio buffering, log writers.
43
+ - **The idea**: wrap raw streams in a buffer so many small reads/writes become few large syscalls.
44
+ - **Code signals**: per-line/per-byte read/write; unbuffered file or socket I/O in a loop.
45
+ - **Speculative win**: orders-of-magnitude fewer syscalls; less kernel-crossing overhead.
46
+ - **Cost / risk**: flush discipline; buffered data lost on crash without flush.
47
+ - **Validate by**: syscall count (strace/dtrace); throughput.
48
+
49
+ ### 4. Connection / resource pooling
50
+ - **Borrowed from**: DB connection pools, HTTP keep-alive.
51
+ - **The idea**: reuse connections/clients from a pool instead of establishing a new one per call.
52
+ - **Code signals**: new client/connection created per request; TLS/handshake cost per call.
53
+ - **Speculative win**: removes setup/teardown latency from every call.
54
+ - **Cost / risk**: pool sizing; stale-connection handling.
55
+ - **Validate by**: per-call latency breakdown; handshake counts.
56
+
57
+ ### 5. Zero-copy transfer (`sendfile` / `splice` / `mmap`)
58
+ - **Borrowed from**: kernel I/O, high-throughput servers, databases.
59
+ - **The idea**: avoid copying bytes through user space — `sendfile`/`splice` send file→socket straight from the page cache (DMA to the NIC, no user-space round-trip), `mmap` for large reads, slice-not-copy buffer handling.
60
+ - **Code signals**: `read()`-into-buffer-then-`write()` loops for large payloads the app never inspects; many intermediate buffer copies.
61
+ - **Speculative win**: a static-file send path *might* drop from ~4 copies to ~2 (or near-0 with NIC scatter-gather), cutting CPU and memory bandwidth; reported CPU drops are large but workload-specific.
62
+ - **Cost / risk**: only helps when the app doesn't need to touch the bytes; `mmap` page-fault and lifetime subtleties; platform-specific (`sendfile`/`splice` are Linux).
63
+ - **Validate by**: CPU/bandwidth profiling on the transfer path; copy count via `perf`/`strace` — profile via perf-design.
64
+
65
+ ### 6. Async batched submission with io_uring
66
+ - **Borrowed from**: Linux io_uring, AIO.
67
+ - **The idea**: submit many I/O operations in one batch and reap completions asynchronously over a shared submission/completion ring. Registered (pre-pinned) buffers and registered file descriptors let the kernel skip per-op mapping/lookup; zero-copy send is supported, and zero-copy *receive* landed in Linux 6.15 (2025).
68
+ - **Code signals**: many independent reads/writes issued one syscall at a time; epoll loops with high syscall overhead under high connection counts.
69
+ - **Speculative win**: fewer syscalls and deeper queue depth *might* raise throughput; public io_uring numbers cite ~30-40% single-flow gains and 2-2.5× over epoll on some network workloads — treat as a ceiling, not a promise.
70
+ - **Cost / risk**: significant complexity; Linux-only and kernel-version-sensitive (newest features need recent kernels); ordering/error handling; buffer lifetime under zero-copy. Zero-copy *receive* in particular is not generally available on any 6.15 host — it requires NIC support for header/data split, flow steering, and RSS, so treat it as conditional on the hardware, not a given.
71
+ - **Validate by**: IOPS/throughput benchmark and syscall counts (`strace -c`) vs the current path — profile via perf-design.
72
+
73
+ ### 7. Vectored I/O (`readv`/`writev`)
74
+ - **Borrowed from**: scatter/gather I/O, `readv`/`writev`/`preadv`/`pwritev`.
75
+ - **The idea**: read or write several non-contiguous buffers in a single syscall instead of one syscall per buffer (e.g. write a header and body together without concatenating them first).
76
+ - **Code signals**: multiple back-to-back `write()`s of related buffers; allocating a temp buffer just to concatenate fragments before one write.
77
+ - **Speculative win**: one syscall replaces several, and avoids the concatenation copy/allocation.
78
+ - **Cost / risk**: minor — iovec setup; per-syscall byte limits (`IOV_MAX`).
79
+ - **Validate by**: syscall count (`strace -c`); throughput on the fragmented-write path.
80
+
81
+ ### 8. Project only what you need (column/field pushdown)
82
+ - **Borrowed from**: columnar databases, GraphQL field selection.
83
+ - **The idea**: fetch only required columns/fields rather than `SELECT *` or full objects; push filters/predicates down to the store.
84
+ - **Code signals**: `SELECT *` then use two fields; fetch full document to read one field; filter in app after fetching everything.
85
+ - **Speculative win**: less data transferred, deserialized, and held.
86
+ - **Cost / risk**: more specific queries to maintain; index coverage.
87
+ - **Validate by**: bytes transferred; query timing — profile via perf-design.
88
+
89
+ ### 9. Cheaper serialization format
90
+ - **Borrowed from**: RPC systems (protobuf, FlatBuffers, Cap'n Proto), columnar formats.
91
+ - **The idea**: replace verbose text serialization (JSON/XML) on hot paths with a compact binary format (protobuf), or a zero-parse format (FlatBuffers/Cap'n Proto) where fields are read directly out of the wire buffer with no unpacking step — good for read-mostly data.
92
+ - **Code signals**: JSON encode/decode showing up on a hot path; large text payloads; decode-then-read-one-field access patterns.
93
+ - **Speculative win**: less CPU for (de)serialization and smaller payloads; zero-parse formats *might* make field reads near-free by skipping the decode step entirely.
94
+ - **Cost / risk**: schema management and interop cost; zero-parse formats trade serialize-side speed and in-place mutability (arena allocation) for read speed, so they fit read-mostly, not write-heavy, data.
95
+ - **Validate by**: (de)serialization CPU and payload size benchmark vs the current format — profile via perf-design.
96
+
97
+ ### 10. Compression on the wire / at rest
98
+ - **Borrowed from**: storage engines, CDNs (gzip/zstd/lz4).
99
+ - **The idea**: compress large payloads to trade CPU for bandwidth where the link or disk is the bottleneck — lz4 for max speed at a modest ratio, zstd for a notably better ratio at higher (but still fast) CPU cost.
100
+ - **Code signals**: large repetitive payloads over a network/disk boundary; bandwidth-bound transfers.
101
+ - **Speculative win**: fewer bytes moved; *might* be faster when I/O-bound. On fast links lz4's lighter CPU often wins; on slow links zstd's better ratio often wins — the crossover is workload-specific.
102
+ - **Cost / risk**: CPU cost; counterproductive when CPU-bound or data is incompressible.
103
+ - **Validate by**: end-to-end time with compression on/off and across codecs/levels; compression ratio — profile via perf-design.
104
+
105
+ ### 11. Read-ahead / prefetch / pagination tuning
106
+ - **Borrowed from**: OS readahead, DB prefetchers.
107
+ - **The idea**: fetch the next chunk before it's needed (prefetch upcoming pages), or right-size page/fetch sizes so you neither over-fetch nor make too many round-trips.
108
+ - **Code signals**: tiny page sizes causing many round-trips; strictly sequential consumption that could prefetch.
109
+ - **Speculative win**: hides fetch latency; fewer round-trips.
110
+ - **Cost / risk**: wasted prefetch if access turns random; memory for buffered pages.
111
+ - **Validate by**: round-trip count and latency across page sizes — profile via perf-design.
112
+
113
+ ### 12. Coalesce / debounce chatty calls
114
+ - **Borrowed from**: UI event debouncing, write coalescing.
115
+ - **The idea**: merge bursts of small requests/writes to the same target within a window into one call.
116
+ - **Code signals**: high-frequency small updates to the same resource; per-keystroke/per-event I/O.
117
+ - **Speculative win**: fewer total operations; less load on the target.
118
+ - **Cost / risk**: added latency to first effect; lost intermediate states.
119
+ - **Validate by**: operation count; latency budget check — profile via perf-design.
120
+
121
+ ### 13. Disable Nagle on small-message latency paths (`TCP_NODELAY`)
122
+ - **Borrowed from**: low-latency RPC/gRPC, trading systems, interactive protocols.
123
+ - **The idea**: Nagle's algorithm holds small writes waiting for an ACK while the peer's delayed-ACK holds the ACK waiting for data — a feedback loop that *can* inject up to ~40 ms stalls per request-response. Setting `TCP_NODELAY` (and/or coalescing app-side into one write) breaks it.
124
+ - **Code signals**: request/response protocol with small payloads; a write-then-immediately-read round-trip per call; sockets left at defaults; sporadic ~40 ms latency spikes.
125
+ - **Speculative win**: tail latency on small synchronous round-trips *might* collapse by tens of milliseconds.
126
+ - **Cost / risk**: more, smaller packets — keep Nagle on for bulk-transfer paths; only a win for latency-sensitive small messages, not throughput.
127
+ - **Validate by**: per-request latency distribution (p99/tail) with `TCP_NODELAY` on/off; packet capture showing delayed-ACK stalls — profile via perf-design.
128
+
129
+ ### 14. Direct I/O for self-cached / streaming workloads (`O_DIRECT`)
130
+ - **Borrowed from**: databases (WAL/data files), high-throughput storage engines.
131
+ - **The idea**: bypass the kernel page cache so reads/writes go straight to disk, when the app maintains its own cache or streams data it won't re-read — avoiding double-buffering and cache pollution.
132
+ - **Code signals**: large sequential reads/writes of write-once or app-cached data; an app-level buffer cache layered on top of the OS page cache; cache thrash from streaming bulk data.
133
+ - **Speculative win**: less memory pressure and CPU copy overhead; more predictable latency for self-managing engines.
134
+ - **Cost / risk**: strict sector-alignment requirements; loses kernel readahead/caching, so it *hurts* re-read-heavy or small-random workloads; mixing `O_DIRECT` and buffered access to the same file is unsafe.
135
+ - **Validate by**: throughput and memory/page-cache pressure with direct vs buffered I/O on the real access pattern — profile via perf-design.
@@ -0,0 +1,137 @@
1
+ # Memory & Data Locality — Perf-Scout Strategy Lens
2
+
3
+ > **When to load this lens**: CPU-bound hot paths, large object graphs, per-element
4
+ > processing, arrays/collections of records, pointer-heavy traversal, allocation
5
+ > churn.
6
+ >
7
+ > **Where these ideas come from**: data-oriented design (game engines, Mike
8
+ > Acton), HPC, and database storage engines — plus the hard truth that a main-
9
+ > memory access can cost ~50-100× an L1 hit (L1 ~1-5 cycles vs DRAM ~100-200
10
+ > cycles), so *how data is laid out in memory often matters more than the
11
+ > instructions over it*. Every entry is a *candidate* hypothesis, not a proven
12
+ > win. Cite `file:line`, attribute the source, give a validation path.
13
+
14
+ ## Detection signals (where this lens might apply — not proof)
15
+ - Arrays/lists of heap-allocated objects (array of pointers) iterated in a hot loop.
16
+ - Hot loops that touch one or two fields of a large struct/object per element.
17
+ - Pointer chasing: linked lists, trees, graphs walked per element on a hot path.
18
+ - Frequent small allocations/frees inside a loop; high GC/allocator pressure.
19
+ - Wide structs with mixed hot and cold fields accessed together.
20
+ - Multi-threaded code mutating adjacent fields/counters (false-sharing risk).
21
+ - Random-access patterns over large arrays (cache/TLB-miss prone).
22
+ - Large working sets (multi-GB) with random access — TLB-pressure prone.
23
+ - Multi-socket servers where threads may touch memory pinned to a remote NUMA node.
24
+
25
+ ## Strategies
26
+
27
+ ### 1. Struct-of-Arrays (SoA) instead of Array-of-Structs (AoS)
28
+ - **Borrowed from**: data-oriented design (game engines), GPU/SIMD layouts.
29
+ - **The idea**: store each field in its own contiguous array so a loop that touches one field streams only that field through cache, instead of pulling whole wide records.
30
+ - **Code signals**: hot loop reads `obj.x` for every `obj` in an array of fat objects; vectorizable per-field math.
31
+ - **Speculative win**: fewer cache lines touched per element; enables SIMD; can be multiples on memory-bound loops.
32
+ - **Cost / risk**: invasive layout change; worse when most fields are used together.
33
+ - **Validate by**: cache-miss counters before/after; benchmark the hot loop — perf-design.
34
+
35
+ ### 2. Hot/cold field splitting
36
+ - **Borrowed from**: data-oriented design, database row layout.
37
+ - **The idea**: split frequently-accessed ("hot") fields into a compact struct and move rarely-used ("cold") fields behind a pointer/side table, so hot iteration packs more elements per cache line.
38
+ - **Code signals**: a large struct where the loop uses 2 of 15 fields; "metadata" fields rarely read on the hot path.
39
+ - **Speculative win**: more useful elements per cache line; denser hot scans.
40
+ - **Cost / risk**: indirection to reach cold data; refactor cost.
41
+ - **Validate by**: measure bytes-touched and cache misses on the hot loop.
42
+
43
+ ### 3. Arena / pool / bump allocation
44
+ - **Borrowed from**: game engines, compilers (region allocation), DB buffer pools.
45
+ - **The idea**: allocate many same-lifetime objects from one contiguous arena and free them en masse, replacing scattered malloc/free with pointer bumps.
46
+ - **Code signals**: many short-lived small allocations per frame/request; allocator time in the profile; fragmentation.
47
+ - **Speculative win**: near-free allocation, contiguous layout, one bulk free; less fragmentation and GC pressure.
48
+ - **Cost / risk**: lifetime discipline; misuse → use-after-free or leaks.
49
+ - **Validate by**: allocation-count/alloc-time and locality benchmarks.
50
+
51
+ ### 4. Object pooling / freelist reuse
52
+ - **Borrowed from**: game engines, connection pools.
53
+ - **The idea**: recycle objects from a freelist instead of allocating/collecting them each cycle.
54
+ - **Code signals**: allocate-then-discard of the same type every iteration; GC pauses correlated with churn.
55
+ - **Speculative win**: removes per-iteration allocation and GC pressure.
56
+ - **Cost / risk**: must reset reused state fully; pool sizing; lifetime bugs.
57
+ - **Validate by**: allocations/op and GC-pause metrics.
58
+
59
+ ### 5. Eliminate pointer chasing (flatten / index by offset)
60
+ - **Borrowed from**: cache-aware data structures, ECS storage.
61
+ - **The idea**: replace pointer-linked structures with contiguous arrays indexed by integer handles (e.g. store a tree/graph in arrays, reference children by index), so traversal streams memory.
62
+ - **Code signals**: linked lists/trees/graphs walked on a hot path; each step dereferences a fresh heap node.
63
+ - **Speculative win**: prefetch-friendly sequential access; far fewer cache/TLB misses.
64
+ - **Cost / risk**: handle invalidation; less ergonomic than pointers.
65
+ - **Validate by**: cache-miss counters; traversal benchmark.
66
+
67
+ ### 6. Pack and align structs
68
+ - **Borrowed from**: systems programming, network protocol design.
69
+ - **The idea**: reorder fields to remove padding, shrink types, and use bitfields/packed enums so more elements fit per cache line; align hot data to cache-line boundaries.
70
+ - **Code signals**: structs with mixed-size fields and visible padding; enums stored as ints.
71
+ - **Speculative win**: smaller working set; more elements per line.
72
+ - **Cost / risk**: misalignment can hurt; packing can add masking cost.
73
+ - **Validate by**: `sizeof`/layout inspection; benchmark.
74
+
75
+ ### 7. Avoid false sharing
76
+ - **Borrowed from**: HPC, lock-free engineering.
77
+ - **The idea**: pad/separate per-thread counters and frequently-written fields onto distinct (typically 64-byte) cache lines so cores writing logically-independent data don't bounce a shared line.
78
+ - **Code signals**: per-thread counters/flags packed in one array or struct; multi-core write-heavy code with surprising scaling loss (more threads = slower).
79
+ - **Speculative win**: removes cache-line ping-pong; could recover most of the lost multi-core scaling on the affected path.
80
+ - **Cost / risk**: memory overhead from padding (~56 bytes/counter on a 64-byte line); padding cold/read-mostly data is wasted.
81
+ - **Validate by**: `perf c2c` cache-line contention profiling; scaling benchmark across thread counts.
82
+
83
+ ### 8. Improve traversal order for locality (tiling/blocking)
84
+ - **Borrowed from**: cache-aware algorithms, image processing, HPC.
85
+ - **The idea**: iterate in memory order (row-major vs column-major), tile/block large traversals into sub-blocks sized to a cache level, and group accesses to the same region. (For machine-portable reuse, see cache-oblivious recursion below.)
86
+ - **Code signals**: 2D arrays/matrices traversed against storage order; large random strides; nested loops with poor reuse.
87
+ - **Speculative win**: sequential access, fewer misses; tiling keeps the working set hot across reuse.
88
+ - **Cost / risk**: loop restructuring; tile-size must be tuned per cache/machine and can age.
89
+ - **Validate by**: cache-miss counters; benchmark across tile sizes.
90
+
91
+ ### 9. Shrink the working set
92
+ - **Borrowed from**: HPC, embedded.
93
+ - **The idea**: use smaller representations (smaller ints, quantized floats, interned/dictionary-encoded values, columnar slices) so more of the live data fits in cache.
94
+ - **Code signals**: 64-bit fields where 16/32 suffice; repeated large strings; wide intermediates.
95
+ - **Speculative win**: more data resident in cache; less bandwidth.
96
+ - **Cost / risk**: precision/range loss; encode/decode overhead.
97
+ - **Validate by**: bandwidth/cache metrics; correctness on the narrowed type.
98
+
99
+ ### 10. Prefetch and batch random access
100
+ - **Borrowed from**: database storage engines, HPC.
101
+ - **The idea**: gather the indices/keys first, sort or group them, then access in a cache/prefetch-friendly order; optionally issue explicit software prefetch hints (`__builtin_prefetch`) a few iterations ahead where the access pattern is known but the hardware prefetcher can't see it.
102
+ - **Code signals**: random gather over a big array/table driven by an unsorted key list; pointer-chasing loops the hardware prefetcher can't follow.
103
+ - **Speculative win**: turns random misses into more predictable access; sorted-gather and ahead-of-time prefetch might hide much of the miss latency.
104
+ - **Cost / risk**: extra sort/gather step; software prefetch is fragile — if the hardware prefetcher already covers the pattern it adds overhead and can be *slower*, and pointer-chains serialize, limiting prefetch depth.
105
+ - **Validate by**: benchmark sorted-gather vs. random and with/without prefetch hints; cache-miss counters.
106
+
107
+ ### 11. Copy-on-write / share immutable data
108
+ - **Borrowed from**: functional data structures, OS page management.
109
+ - **The idea**: share immutable buffers/strings/slices instead of deep-copying; copy only on mutation.
110
+ - **Code signals**: defensive deep copies of large data passed around read-only.
111
+ - **Speculative win**: removes large copies and the allocations behind them.
112
+ - **Cost / risk**: aliasing bugs if mutation sneaks in; needs clear ownership.
113
+ - **Validate by**: count/size of copies eliminated; benchmark.
114
+
115
+ ### 12. Cache-oblivious recursive blocking
116
+ - **Borrowed from**: cache-oblivious algorithms (Leiserson/Prokop, MIT) — distinct from hand-tuned tiling.
117
+ - **The idea**: recursively subdivide a problem (matrix multiply, transpose, scans) until sub-blocks fit some cache level; the divide-and-conquer structure gets good reuse at *every* cache level without hard-coding a tile size for a specific machine.
118
+ - **Code signals**: large dense linear-algebra / grid traversals; a tiled loop whose tile size is tuned per-machine and ages badly.
119
+ - **Speculative win**: portable locality across cache levels and CPUs; could approach tuned-tiling reuse without per-target tuning.
120
+ - **Cost / risk**: recursion overhead at small sizes (needs a base-case cutoff); harder to read than a flat loop.
121
+ - **Validate by**: cache-miss counters at L2/L3; benchmark vs. flat and hand-tiled loops across machines.
122
+
123
+ ### 13. Huge pages to cut TLB misses
124
+ - **Borrowed from**: database engines, HPC, OS memory management.
125
+ - **The idea**: back large hot allocations with 2 MB huge pages (or `madvise`/THP) so each TLB entry maps far more memory — a 2 MB page covers 512× the address space of a 4 KB page, shrinking page-walk overhead on large working sets.
126
+ - **Code signals**: multi-GB working set with broad/random access; profile shows `dTLB-load-misses` or page-walk cycles high.
127
+ - **Speculative win**: fewer TLB misses and page walks; a page walk is much costlier than a TLB hit, and its cost varies widely with page-walk-cache and cache/memory residency (so measure it rather than assuming a fixed cycle count). Candidate gain on TLB-bound large-footprint loops.
128
+ - **Cost / risk**: not universal — DBs with sparse/random access can *regress* under transparent huge pages; memory waste and allocation latency; needs OS/allocator support.
129
+ - **Validate by**: `perf stat -e dTLB-load-misses,dtlb_load_misses.walk_*`; benchmark with huge pages on vs off.
130
+
131
+ ### 14. NUMA-aware allocation (first-touch / local placement)
132
+ - **Borrowed from**: HPC, multi-socket server engineering.
133
+ - **The idea**: on multi-socket boxes, place each thread's hot data on its own NUMA node — rely on first-touch (the thread that first *writes* a page owns its placement) or explicit `numa_alloc`/`mbind` — so cores read local rather than remote memory.
134
+ - **Code signals**: multi-socket server; data allocated/initialized by one thread then crunched by threads pinned to other sockets; bandwidth-bound parallel loops that scale poorly past one socket.
135
+ - **Speculative win**: remote access costs ~2× latency and ~1.8× less bandwidth than local; localizing could recover much of that on bandwidth-bound paths.
136
+ - **Cost / risk**: requires thread pinning + first-touch discipline; shared/migrating data defeats it; single-socket machines see no benefit.
137
+ - **Validate by**: `numastat` / per-node bandwidth counters; pinned local-vs-remote benchmark — profile via perf-design.
@@ -0,0 +1,126 @@
1
+ # Parallelism & Vectorization — Perf-Scout Strategy Lens
2
+
3
+ > **When to load this lens**: independent work done sequentially, map/reduce
4
+ > shapes, numeric kernels, idle cores, large batch processing, request fan-out.
5
+ >
6
+ > **Where these ideas come from**: HPC, GPU programming, high-frequency trading,
7
+ > and lock-free systems engineering. Parallelism is powerful but adds real
8
+ > complexity, so the best candidates are *embarrassingly parallel* work or tight
9
+ > numeric loops that vectorize. Every entry is a *candidate* hypothesis, not a
10
+ > proven win. Cite `file:line`, attribute the source, give a validation path.
11
+ > Note for the orchestrator: parallelism usually pays off only after algorithmic,
12
+ > locality, and I/O wins — flag it, but rank honestly against cheaper lenses.
13
+
14
+ ## Detection signals (where this lens might apply — not proof)
15
+ - Loops over independent items processed one at a time (map shape, no cross-iteration dependency).
16
+ - Numeric inner loops over arrays (sums, dot products, element-wise math, filters).
17
+ - Sequential I/O fan-out (N independent requests awaited one after another).
18
+ - Aggregations (sum/count/min/max/group-by) over large datasets.
19
+ - Single-threaded hot path on a multi-core machine; cores idle under load.
20
+ - Heavy per-request CPU work that could pipeline with I/O.
21
+
22
+ ## Strategies
23
+
24
+ ### 1. Data parallelism over independent items
25
+ - **Borrowed from**: map-reduce, GPU SIMT, parallel STL.
26
+ - **The idea**: split an independent-item loop across cores (thread pool, parallel map, rayon/`parallelStream`/`multiprocessing`), then combine.
27
+ - **Code signals**: a pure map over a large collection with no shared mutable state.
28
+ - **Speculative win**: near-linear speedup up to core count for CPU-bound maps.
29
+ - **Cost / risk**: thread/process overhead; false sharing; only wins above a work threshold.
30
+ - **Validate by**: scaling benchmark across thread counts — perf-design.
31
+
32
+ ### 2. SIMD / vectorization
33
+ - **Borrowed from**: HPC, codecs, columnar/vectorized DB execution.
34
+ - **The idea**: process multiple elements per instruction — restructure loops for auto-vectorization, or use explicit intrinsics / portable SIMD (Rust `std::simd` is still nightly-only as of 2025; `wide`/`std::arch` work on stable); pair with SoA layout.
35
+ - **Code signals**: tight numeric loops over contiguous arrays; element-wise transforms; predicate-heavy filters.
36
+ - **Speculative win**: up to lane count (e.g. ~4–8× for f32 on AVX2; AVX-512 rarely reaches the full 16× because of frequency throttling, register pressure, and memory bandwidth).
37
+ - **Cost / risk**: layout-dependent; branch-heavy loops resist vectorization; portability and wider-vector downclocking.
38
+ - **Validate by**: compiler vectorization report (`-fopt-info-vec` / `-Rpass=loop-vectorize`); kernel microbenchmark.
39
+
40
+ ### 3. Concurrent I/O fan-out
41
+ - **Borrowed from**: async runtimes, service meshes.
42
+ - **The idea**: issue N independent I/O calls concurrently (gather/`Promise.all`/`JoinSet`) instead of awaiting them in sequence.
43
+ - **Code signals**: `for item: await fetch(item)` — serial awaits with no dependency between iterations.
44
+ - **Speculative win**: wall time *could* drop from the sum of the calls toward the slowest single call, if the calls are truly independent and the downstream can absorb the concurrency.
45
+ - **Cost / risk**: downstream rate limits; needs bounded concurrency to avoid overload.
46
+ - **Validate by**: end-to-end latency with realistic concurrency caps.
47
+
48
+ ### 4. Pipeline parallelism (overlap stages)
49
+ - **Borrowed from**: CPU pipelines, stream processors, build systems.
50
+ - **The idea**: split a multi-stage process into stages connected by bounded queues so stage k+1 works on item i while stage k works on item i+1 (overlap CPU with I/O especially).
51
+ - **Code signals**: read→transform→write done fully per item; CPU idle during I/O and vice versa.
52
+ - **Speculative win**: throughput rises toward the slowest stage's rate; hides latency.
53
+ - **Cost / risk**: backpressure and queue sizing; harder error handling.
54
+ - **Validate by**: throughput benchmark; per-stage utilization.
55
+
56
+ ### 5. Parallel reduction / tree aggregation
57
+ - **Borrowed from**: HPC reductions, map-reduce combiners.
58
+ - **The idea**: compute partial aggregates per shard/thread, then combine in a tree, instead of a single sequential fold.
59
+ - **Code signals**: sequential `sum`/`count`/`group-by` over a huge dataset.
60
+ - **Speculative win**: parallel speedup on the reduce with associative/commutative ops.
61
+ - **Cost / risk**: requires associativity; floating-point result ordering changes.
62
+ - **Validate by**: scaling benchmark; numeric-stability check for float reductions.
63
+
64
+ ### 6. Lock-free structures / optimistic reads on hot shared state
65
+ - **Borrowed from**: HFT, lock-free systems engineering; seqlocks from the Linux kernel.
66
+ - **The idea**: replace a contended mutex on a hot shared structure with atomics/CAS or a lock-free queue. For read-mostly state, a *seqlock* lets readers retry optimistically without taking a lock (writers still serialize via an embedded lock) — note this is optimistic, not lock-free/wait-free in the strict sense.
67
+ - **Code signals**: a single hot mutex showing up as contention; many threads hammering one counter/queue; a read-mostly value guarded by a lock.
68
+ - **Speculative win**: *might* remove lock contention and context-switch stalls under load; readers may avoid blocking entirely.
69
+ - **Cost / risk**: very high — true lock-free code is subtle (ABA, memory ordering, reclamation); seqlock readers must tolerate retries and must not observe torn writes. Treat as expert-only.
70
+ - **Validate by**: contention/off-CPU profiling; stress tests; model-checking where feasible.
71
+
72
+ ### 7. Sharding to reduce contention
73
+ - **Borrowed from**: concurrent hash maps, striped locks.
74
+ - **The idea**: partition shared state into N independent shards (striped locks, per-core/per-thread accumulators merged later) so writers rarely collide.
75
+ - **Code signals**: one global lock/counter/map under multi-threaded write load.
76
+ - **Speculative win**: contention drops ~1/N; better multi-core scaling.
77
+ - **Cost / risk**: cross-shard operations get costlier; merge step.
78
+ - **Validate by**: scaling benchmark; contention metrics.
79
+
80
+ ### 8. Work-stealing for irregular workloads
81
+ - **Borrowed from**: work-stealing schedulers (originated in Multilisp, formalized by Cilk; today rayon, Tokio, Java fork/join).
82
+ - **The idea**: use a work-stealing pool so idle cores grab tasks from busy ones when per-item cost varies widely.
83
+ - **Code signals**: parallel work with highly uneven item costs causing load imbalance.
84
+ - **Speculative win**: better core utilization than static partitioning.
85
+ - **Cost / risk**: scheduler overhead for tiny tasks; granularity tuning.
86
+ - **Validate by**: utilization and wall-time benchmark vs. static split.
87
+
88
+ ### 9. GPU / accelerator offload
89
+ - **Borrowed from**: GPU computing, ML kernels.
90
+ - **The idea**: move massively-parallel, arithmetic-heavy, regular work (large element-wise/matrix/convolution ops) to a GPU or SIMD accelerator.
91
+ - **Code signals**: huge regular numeric workloads; matrix/tensor math; image/signal processing on CPU.
92
+ - **Speculative win**: order-of-magnitude on suitable kernels.
93
+ - **Cost / risk**: transfer overhead, deployment complexity; only wins when compute ≫ transfer.
94
+ - **Validate by**: kernel benchmark including host↔device transfer.
95
+
96
+ ### 10. Async over blocking for I/O-bound concurrency
97
+ - **Borrowed from**: event-driven servers (nginx, Node, Tokio).
98
+ - **The idea**: replace thread-per-blocking-call with async I/O so one thread handles many in-flight operations, cutting context-switch and stack overhead at high concurrency.
99
+ - **Code signals**: thread-per-request/-connection under high concurrency; many threads blocked in I/O.
100
+ - **Speculative win**: far higher connection/request concurrency per core; less memory.
101
+ - **Cost / risk**: async complexity; a stray blocking call stalls the loop.
102
+ - **Validate by**: load test at target concurrency; off-CPU profiling.
103
+
104
+ ### 11. False-sharing-aware partitioning
105
+ - **Borrowed from**: cache-coherence engineering; LMAX Disruptor's cache-line padding.
106
+ - **The idea**: when threads write to nearby addresses that share a 64-byte cache line (per-thread counters in one array, fields in one struct), pad or align each thread's data to its own line so writes stop ping-ponging the line between cores.
107
+ - **Code signals**: per-thread/per-core slots packed in one contiguous array or struct, each mutated by a different thread; flat scaling or *negative* scaling as threads increase.
108
+ - **Speculative win**: removes coherence traffic on the hot line — candidate for a large jump once a false-sharing line is the bottleneck (reported impacts have ranged from ~25% up to several-fold).
109
+ - **Cost / risk**: padding wastes cache/memory; only helps when false sharing is the actual cause, not true contention.
110
+ - **Validate by**: `perf c2c` (cache-to-cache / HITM) to locate the line; scaling benchmark before/after padding.
111
+
112
+ ### 12. NUMA-aware parallelism
113
+ - **Borrowed from**: HPC and multi-socket database/server tuning.
114
+ - **The idea**: on multi-socket / multi-NUMA-node machines, pin threads near the memory they touch (first-touch allocation, `numactl`, affinity) so hot data stays in the local node instead of paying cross-node access latency.
115
+ - **Code signals**: a parallel workload that scales within one socket but stalls or regresses across sockets; large shared buffers allocated on one node and read by all.
116
+ - **Speculative win**: cuts remote-memory latency on cross-socket paths; better scaling past one NUMA node.
117
+ - **Cost / risk**: placement is platform-specific and brittle; no benefit on single-socket hardware; can hurt if it fights the OS scheduler.
118
+ - **Validate by**: NUMA-local vs default scaling benchmark; `numastat` / remote-access counters.
119
+
120
+ ### 13. Match the queue to the producer/consumer count
121
+ - **Borrowed from**: lock-free systems engineering; LMAX Disruptor; SPSC/MPSC/SPMC queue families.
122
+ - **The idea**: a queue hand-off forced through a general MPMC structure when the real shape is single-producer/single-consumer (or single-consumer) can switch to a specialized SPSC/MPSC ring buffer with far less synchronization — SPSC needs almost none.
123
+ - **Code signals**: a general concurrent/locking queue on a hot hand-off path whose actual producer/consumer counts are fixed and small.
124
+ - **Speculative win**: cheaper enqueue/dequeue and less contention than a fully general queue on that path.
125
+ - **Cost / risk**: specialized queues have stricter usage contracts; wrong producer/consumer assumptions corrupt data; FIFO may relax.
126
+ - **Validate by**: throughput/latency microbenchmark of the hand-off; contention profiling under target load.
@@ -0,0 +1,117 @@
1
+ # Parked Perf-Scout Idea Template
2
+
3
+ > Used by `perf-scout` to park each candidate idea into `.work/backlog/<id>.md`.
4
+ > These are **speculative ideas**, not findings — the frontmatter and body keep
5
+ > that framing. The user elevates anything worth pursuing via
6
+ > `/agile-workflow:scope`, or hands it to `/agile-workflow:perf-design` to measure
7
+ > and validate.
8
+
9
+ ## File location
10
+
11
+ Parked ideas go to `.work/backlog/<id>.md`. By default only **Investigate-first**
12
+ and **Worth-a-look** ideas are parked — long-shots stay in the report so the
13
+ backlog doesn't fill with speculative noise (pass `--park-all` to park every
14
+ tier). Ideas are investigation candidates, never release blockers — there is no
15
+ active-tier or gate path out of perf-scout. The user chooses what to promote.
16
+
17
+ ## ID convention
18
+
19
+ `perf-scout-<short-slug>` — slug describes the idea briefly (kebab-case, ≤ 40
20
+ chars after the prefix). On collision, suffix `-2`, `-3`.
21
+
22
+ Examples:
23
+ - `perf-scout-soa-particle-buffer`
24
+ - `perf-scout-n-plus-1-in-order-loader`
25
+ - `perf-scout-bloom-filter-before-blob-fetch`
26
+ - `perf-scout-hll-distinct-visitors`
27
+
28
+ ## Frontmatter + body template
29
+
30
+ ```yaml
31
+ ---
32
+ id: perf-scout-<short-slug>
33
+ created: YYYY-MM-DD # today's local date
34
+ tags: [perf, idea, <lens-tag>]
35
+ idea_origin: scout # how this entered the backlog (distinguishes from user-parked ideas)
36
+ idea_lens: algorithmic | memory-locality | parallelism | gpu | caching | io-batching | distributed | game-engine | database-internals | compiler-runtime | approximation
37
+ idea_borrowed_from: <source domain — e.g. "LSM trees", "game-engine ECS", "GPU coalescing">
38
+ idea_priority: investigate-first | worth-a-look | long-shot
39
+ idea_location: <file>:<line> # canonical location for idempotency
40
+ idea_source: scout | peer-<agent> | peer-fallback # who generated it
41
+ ---
42
+
43
+ # <one-line idea title>
44
+
45
+ **Location**: `<file>:<line>` · **Lens**: <lens> · **Borrowed from**: <domain> · **Priority**: <tier>
46
+ **Leverage**: <High|Med|Low> · **Applicability**: <Likely|Plausible|Speculative> · **Cost**: <Low|Med|High>
47
+
48
+ > ⚠️ Unvalidated hypothesis — no measurement has been done. This is a candidate to
49
+ > investigate, not a proven win.
50
+
51
+ **The idea**: <2-4 sentences: the specific transform to try here, and the domain technique it borrows.>
52
+
53
+ **Why it might help**: <the speculative mechanism — "might", never "will".>
54
+
55
+ **Validate by**: <how to confirm: the metric to measure / benchmark to write / "profile via /agile-workflow:perf-design".>
56
+
57
+ **Risk**: <one line — correctness, complexity, memory, or behavior-change concern.>
58
+ ```
59
+
60
+ ## Lens tag mapping
61
+
62
+ | Lens | `idea_lens` value | tag |
63
+ |---|---|---|
64
+ | Algorithmic & data structures | `algorithmic` | `algorithmic` |
65
+ | Memory & data locality | `memory-locality` | `memory` |
66
+ | Parallelism & vectorization | `parallelism` | `parallelism` |
67
+ | GPU & accelerators | `gpu` | `gpu` |
68
+ | Caching & memoization | `caching` | `caching` |
69
+ | I/O & batching | `io-batching` | `io` |
70
+ | Distributed systems | `distributed` | `distributed` |
71
+ | Game-engine & realtime | `game-engine` | `realtime` |
72
+ | Database & storage internals | `database-internals` | `storage` |
73
+ | Compiler, runtime & language | `compiler-runtime` | `runtime` |
74
+ | Approximation & precomputation | `approximation` | `approximation` |
75
+
76
+ All carry the umbrella `perf` and `idea` tags. Optionally add `investigate-first`
77
+ to `tags:` for top-tier ideas so `grep -l "investigate-first" .work/backlog/`
78
+ surfaces them fast.
79
+
80
+ ## Idempotency (re-run protection)
81
+
82
+ Before parking, index existing parked ideas:
83
+
84
+ ```bash
85
+ grep -rl "^idea_origin: scout$" .work/backlog/ 2>/dev/null | while read -r f; do
86
+ loc=$(grep -m1 '^idea_location:' "$f" | awk '{print $2}')
87
+ lens=$(grep -m1 '^idea_lens:' "$f" | awk '{print $2}')
88
+ [ -n "$loc" ] && echo "$loc $lens $f"
89
+ done > /tmp/perfscout-existing.txt
90
+ ```
91
+
92
+ For each new idea, check the (`file:line`, `idea_lens`) pair against the index. If
93
+ present, **skip** — don't re-park. Two different lenses proposing different
94
+ transforms at the same site are distinct ideas; keep both. Tally the skip count
95
+ for the report.
96
+
97
+ ## Rules
98
+
99
+ - One idea = one parked file. No bundling (but cluster-level "rethink this layer"
100
+ ideas are themselves a single idea and park as one file).
101
+ - `idea_origin: scout` is required — distinguishes perf-scout ideas from
102
+ user-parked ideas (no `idea_origin`).
103
+ - `idea_location` is required — drives idempotency.
104
+ - The ⚠️ unvalidated-hypothesis line is required in every body. It's the honesty
105
+ contract: these files will be skimmed out of context later, and nothing here
106
+ should read as a confirmed win.
107
+ - Keep the body tight. Deep analysis lives in `perf-scout-report.md`; backlog
108
+ files get skimmed.
109
+ - After parking all ideas, commit in one commit:
110
+ `perf-scout: park <N> ideas (<scope>)`. Use explicit paths, never `git add -A`,
111
+ if the working tree was already dirty.
112
+
113
+ ## Opt-out
114
+
115
+ If invoked with `--no-park`, skip this phase entirely. Write only the report and
116
+ note the skipped count in its summary, so it's transparent the substrate was
117
+ bypassed.