@reicek/neataptic-ts 0.1.24 → 0.1.26

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 (215) hide show
  1. package/.github/copilot-instructions.md +11 -0
  2. package/.github/skills/trace-analyzer-extension/SKILL.md +3 -3
  3. package/.github/skills/trace-analyzer-extension/assets/extension-checklist.md +1 -1
  4. package/.github/skills/trace-analyzer-extension/references/analyzer-extension-workflow.md +1 -1
  5. package/.github/skills/trace-audit-reporting/SKILL.md +3 -3
  6. package/.github/skills/trace-audit-reporting/references/trace-analysis-workflow.md +1 -1
  7. package/.github/workflows/ci.yml +3 -3
  8. package/.github/workflows/deploy-pages.yml +6 -6
  9. package/.github/workflows/manual_release_pipeline.yml +3 -3
  10. package/.github/workflows/publish.yml +18 -19
  11. package/.github/workflows/release_dispatch.yml +3 -3
  12. package/package.json +26 -20
  13. package/plans/Flappy_Bird_Folder_Documentation_Pass.md +4 -4
  14. package/plans/README.md +24 -0
  15. package/plans/Roadmap.md +62 -40
  16. package/plans/analyze-trace-solid-split.plans.md +66 -0
  17. package/plans/architecture-solid-split.plans.md +9 -15
  18. package/plans/asciiMaze-typescript-repair.plans.md +1 -1
  19. package/plans/generate-docs-solid-split.plans.md +87 -0
  20. package/plans/methods-docs.plans.md +25 -1
  21. package/plans/methods-solid-split.plans.md +14 -14
  22. package/plans/neat-docs.plans.md +9 -1
  23. package/plans/neat-test-surface-repair.plans.md +1 -1
  24. package/plans/render-docs-html-solid-split.plans.md +68 -0
  25. package/plans/src-no-explicit-any-cleanup.plans.md +1 -1
  26. package/plans/utils-docs.plans.md +6 -1
  27. package/scripts/analyze-trace/analyze-trace.analysis.ts +479 -0
  28. package/scripts/analyze-trace/analyze-trace.constants.ts +35 -0
  29. package/scripts/analyze-trace/analyze-trace.io.ts +69 -0
  30. package/scripts/analyze-trace/analyze-trace.report.ts +100 -0
  31. package/scripts/analyze-trace/analyze-trace.shared.ts +116 -0
  32. package/scripts/analyze-trace/analyze-trace.ts +45 -0
  33. package/scripts/analyze-trace/analyze-trace.types.ts +72 -0
  34. package/scripts/assets/theme.css +80 -23
  35. package/scripts/copy-examples.ts +239 -0
  36. package/scripts/export-onnx.ts +223 -0
  37. package/scripts/generate-bench-tables.ts +378 -37
  38. package/scripts/generate-docs/generate-docs.constants.ts +107 -0
  39. package/scripts/generate-docs/generate-docs.order.ts +355 -0
  40. package/scripts/generate-docs/generate-docs.state.ts +31 -0
  41. package/scripts/generate-docs/generate-docs.targets.ts +165 -0
  42. package/scripts/generate-docs/generate-docs.ts +63 -0
  43. package/scripts/generate-docs/generate-docs.types.ts +112 -0
  44. package/scripts/generate-docs/output/generate-docs.output.folder-index.utils.ts +167 -0
  45. package/scripts/generate-docs/output/generate-docs.output.ordering.utils.ts +353 -0
  46. package/scripts/generate-docs/output/generate-docs.output.readme.utils.ts +420 -0
  47. package/scripts/generate-docs/output/generate-docs.output.ts +123 -0
  48. package/scripts/generate-docs/output/generate-docs.output.warnings.utils.ts +219 -0
  49. package/scripts/generate-docs/symbols/generate-docs.symbols.collection.utils.ts +365 -0
  50. package/scripts/generate-docs/symbols/generate-docs.symbols.jsdoc.utils.ts +373 -0
  51. package/scripts/generate-docs/symbols/generate-docs.symbols.normalize.utils.ts +155 -0
  52. package/scripts/generate-docs/symbols/generate-docs.symbols.render.utils.ts +149 -0
  53. package/scripts/generate-docs/symbols/generate-docs.symbols.signature.utils.ts +289 -0
  54. package/scripts/generate-docs/symbols/generate-docs.symbols.ts +11 -0
  55. package/scripts/mermaid-cli.mjs +102 -22
  56. package/scripts/mermaid-cli.ts +736 -0
  57. package/scripts/render-docs-html/render-docs-html.assets.ts +54 -0
  58. package/scripts/render-docs-html/render-docs-html.mermaid.ts +245 -0
  59. package/scripts/{render-docs-html.sidebar.ts → render-docs-html/render-docs-html.navigation.ts} +141 -144
  60. package/scripts/render-docs-html/render-docs-html.pages.ts +333 -0
  61. package/scripts/render-docs-html/render-docs-html.shared.ts +333 -0
  62. package/scripts/render-docs-html/render-docs-html.types.ts +42 -0
  63. package/scripts/render-docs-html.ts +23 -587
  64. package/scripts/run-docs.ts +238 -0
  65. package/scripts/write-dist-docs-pkg.ts +40 -0
  66. package/src/README.md +75 -75
  67. package/src/architecture/connection/README.md +5 -5
  68. package/src/architecture/layer/README.md +508 -508
  69. package/src/architecture/network/README.md +1458 -1458
  70. package/src/architecture/network/activate/README.md +694 -694
  71. package/src/architecture/network/bootstrap/README.md +77 -77
  72. package/src/architecture/network/connect/README.md +74 -74
  73. package/src/architecture/network/deterministic/README.md +135 -135
  74. package/src/architecture/network/evolve/README.md +364 -364
  75. package/src/architecture/network/gating/README.md +130 -130
  76. package/src/architecture/network/genetic/README.md +399 -399
  77. package/src/architecture/network/mutate/README.md +897 -897
  78. package/src/architecture/network/onnx/README.md +720 -720
  79. package/src/architecture/network/onnx/export/README.md +728 -728
  80. package/src/architecture/network/onnx/export/layers/README.md +450 -450
  81. package/src/architecture/network/onnx/import/README.md +618 -618
  82. package/src/architecture/network/onnx/schema/README.md +32 -32
  83. package/src/architecture/network/prune/README.md +245 -245
  84. package/src/architecture/network/remove/README.md +135 -135
  85. package/src/architecture/network/runtime/README.md +106 -106
  86. package/src/architecture/network/serialize/README.md +542 -542
  87. package/src/architecture/network/slab/README.md +608 -608
  88. package/src/architecture/network/standalone/README.md +212 -212
  89. package/src/architecture/network/stats/README.md +84 -84
  90. package/src/architecture/network/topology/README.md +465 -465
  91. package/src/architecture/network/training/README.md +200 -200
  92. package/src/architecture/node/README.md +5 -5
  93. package/src/architecture/nodePool/README.md +14 -14
  94. package/src/methods/README.md +99 -99
  95. package/src/methods/activation/README.md +189 -189
  96. package/src/methods/cost/README.md +131 -131
  97. package/src/methods/rate/README.md +86 -86
  98. package/src/multithreading/README.md +77 -77
  99. package/src/multithreading/workers/browser/README.md +8 -8
  100. package/src/multithreading/workers/node/README.md +8 -8
  101. package/src/neat/README.md +148 -148
  102. package/src/neat/adaptive/README.md +120 -120
  103. package/src/neat/adaptive/acceptance/README.md +40 -40
  104. package/src/neat/adaptive/complexity/README.md +137 -137
  105. package/src/neat/adaptive/core/README.md +197 -197
  106. package/src/neat/adaptive/lineage/README.md +90 -90
  107. package/src/neat/adaptive/mutation/README.md +284 -284
  108. package/src/neat/compat/README.md +43 -43
  109. package/src/neat/compat/core/README.md +90 -90
  110. package/src/neat/diversity/README.md +35 -35
  111. package/src/neat/diversity/core/README.md +88 -88
  112. package/src/neat/evaluate/README.md +85 -85
  113. package/src/neat/evaluate/auto-distance/README.md +75 -75
  114. package/src/neat/evaluate/entropy-compat/README.md +37 -37
  115. package/src/neat/evaluate/entropy-sharing/README.md +43 -43
  116. package/src/neat/evaluate/fitness/README.md +23 -23
  117. package/src/neat/evaluate/novelty/README.md +120 -120
  118. package/src/neat/evaluate/objectives/README.md +17 -17
  119. package/src/neat/evaluate/shared/README.md +94 -94
  120. package/src/neat/evolve/README.md +96 -96
  121. package/src/neat/evolve/adaptive/README.md +60 -60
  122. package/src/neat/evolve/objectives/README.md +63 -63
  123. package/src/neat/evolve/offspring/README.md +56 -56
  124. package/src/neat/evolve/population/README.md +171 -171
  125. package/src/neat/evolve/runtime/README.md +79 -79
  126. package/src/neat/evolve/speciation/README.md +74 -74
  127. package/src/neat/evolve/warnings/README.md +10 -10
  128. package/src/neat/export/README.md +114 -114
  129. package/src/neat/helpers/README.md +50 -50
  130. package/src/neat/init/README.md +9 -9
  131. package/src/neat/lineage/core/README.md +101 -101
  132. package/src/neat/multiobjective/category/README.md +74 -74
  133. package/src/neat/multiobjective/crowding/README.md +272 -272
  134. package/src/neat/multiobjective/dominance/README.md +171 -171
  135. package/src/neat/multiobjective/fronts/README.md +68 -68
  136. package/src/neat/multiobjective/metrics/README.md +43 -43
  137. package/src/neat/multiobjective/objectives/README.md +31 -31
  138. package/src/neat/multiobjective/shared/README.md +27 -27
  139. package/src/neat/mutation/README.md +97 -97
  140. package/src/neat/mutation/add-conn/README.md +115 -115
  141. package/src/neat/mutation/add-node/README.md +126 -126
  142. package/src/neat/mutation/flow/README.md +149 -149
  143. package/src/neat/mutation/repair/README.md +185 -185
  144. package/src/neat/mutation/select/README.md +117 -117
  145. package/src/neat/mutation/shared/README.md +32 -32
  146. package/src/neat/objectives/README.md +25 -25
  147. package/src/neat/objectives/core/README.md +67 -67
  148. package/src/neat/pruning/README.md +40 -40
  149. package/src/neat/pruning/core/README.md +171 -171
  150. package/src/neat/pruning/facade/README.md +32 -32
  151. package/src/neat/rng/README.md +104 -104
  152. package/src/neat/rng/core/README.md +137 -137
  153. package/src/neat/rng/facade/README.md +50 -50
  154. package/src/neat/selection/README.md +111 -111
  155. package/src/neat/selection/core/README.md +227 -227
  156. package/src/neat/selection/facade/README.md +61 -61
  157. package/src/neat/shared/README.md +163 -163
  158. package/src/neat/speciation/README.md +31 -31
  159. package/src/neat/speciation/threshold/README.md +35 -35
  160. package/src/neat/species/README.md +25 -25
  161. package/src/neat/species/core/README.md +20 -20
  162. package/src/neat/species/core/shared/README.md +18 -18
  163. package/src/neat/species/history/context/README.md +22 -22
  164. package/src/neat/telemetry/accessors/README.md +58 -58
  165. package/src/neat/telemetry/exports/README.md +233 -233
  166. package/src/neat/telemetry/facade/README.md +252 -252
  167. package/src/neat/telemetry/facade/archive/README.md +57 -57
  168. package/src/neat/telemetry/facade/buffer/README.md +43 -43
  169. package/src/neat/telemetry/facade/lineage/README.md +12 -12
  170. package/src/neat/telemetry/facade/objectives/README.md +44 -44
  171. package/src/neat/telemetry/facade/runtime/README.md +26 -26
  172. package/src/neat/telemetry/facade/species/README.md +27 -27
  173. package/src/neat/telemetry/metrics/README.md +696 -696
  174. package/src/neat/telemetry/recorder/README.md +57 -57
  175. package/src/neat/telemetry/types/README.md +32 -32
  176. package/src/neat/topology-intent/README.md +75 -75
  177. package/src/utils/README.md +193 -193
  178. package/test/examples/asciiMaze/browser-entry/README.md +92 -92
  179. package/test/examples/asciiMaze/dashboardManager/README.md +109 -109
  180. package/test/examples/asciiMaze/dashboardManager/telemetry/README.md +28 -28
  181. package/test/examples/asciiMaze/evolutionEngine/README.md +1527 -1527
  182. package/test/examples/asciiMaze/mazeMovement/README.md +105 -105
  183. package/test/examples/asciiMaze/mazeMovement/finalization/README.md +16 -16
  184. package/test/examples/asciiMaze/mazeMovement/policy/README.md +57 -57
  185. package/test/examples/asciiMaze/mazeMovement/runtime/README.md +52 -52
  186. package/test/examples/asciiMaze/mazeMovement/shaping/README.md +46 -46
  187. package/test/examples/flappy_bird/browser-entry/README.md +508 -508
  188. package/test/examples/flappy_bird/browser-entry/host/README.md +101 -101
  189. package/test/examples/flappy_bird/browser-entry/host/resize/README.md +144 -144
  190. package/test/examples/flappy_bird/browser-entry/network-view/README.md +194 -194
  191. package/test/examples/flappy_bird/browser-entry/playback/README.md +278 -278
  192. package/test/examples/flappy_bird/browser-entry/playback/background/README.md +129 -129
  193. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/README.md +502 -502
  194. package/test/examples/flappy_bird/browser-entry/playback/frame-render/README.md +139 -139
  195. package/test/examples/flappy_bird/browser-entry/playback/snapshot/README.md +10 -10
  196. package/test/examples/flappy_bird/browser-entry/playback/trail/README.md +43 -43
  197. package/test/examples/flappy_bird/browser-entry/playback/worker-channel/README.md +30 -30
  198. package/test/examples/flappy_bird/browser-entry/runtime/README.md +59 -59
  199. package/test/examples/flappy_bird/browser-entry/visualization/README.md +276 -276
  200. package/test/examples/flappy_bird/browser-entry/worker-channel/README.md +16 -16
  201. package/test/examples/flappy_bird/constants/README.md +1070 -1070
  202. package/test/examples/flappy_bird/environment/README.md +22 -22
  203. package/test/examples/flappy_bird/evaluation/README.md +32 -32
  204. package/test/examples/flappy_bird/evaluation/rollout/README.md +141 -141
  205. package/test/examples/flappy_bird/flappy-evolution-worker/README.md +425 -425
  206. package/test/examples/flappy_bird/simulation-shared/README.md +170 -170
  207. package/test/examples/flappy_bird/simulation-shared/observation/README.md +109 -109
  208. package/test/examples/flappy_bird/trainer/README.md +325 -325
  209. package/test/examples/flappy_bird/trainer/evaluation/README.md +74 -74
  210. package/scripts/analyze-trace.ts +0 -590
  211. package/scripts/copy-examples.mjs +0 -114
  212. package/scripts/export-onnx.mjs +0 -86
  213. package/scripts/generate-bench-tables.mjs +0 -182
  214. package/scripts/generate-docs.ts +0 -2900
  215. package/scripts/write-dist-docs-pkg.mjs +0 -16
@@ -48,264 +48,265 @@ flowchart TD
48
48
 
49
49
  ## neat/mutation/flow/mutation.flow.ts
50
50
 
51
- ### mutateGenome
51
+ ### applyAddConnMutation
52
52
 
53
53
  ```ts
54
- mutateGenome(
54
+ applyAddConnMutation(
55
55
  genome: GenomeWithMetadata,
56
56
  internal: NeatControllerForMutation,
57
57
  methods: { mutation: unknown; },
58
- ): Promise<void>
58
+ ): void
59
59
  ```
60
60
 
61
- Mutate a single genome based on configured mutation policies.
62
-
63
- This is the orchestration entry point for the `flow/` chapter. It keeps the
64
- per-genome lifecycle linear: adaptive settings are prepared first, then one
65
- probability gate decides whether work happens at all, and only then does the
66
- helper loop ask `select/` for concrete operators.
67
-
68
- The important design choice is that mutation amount is resolved after the
69
- mutate-or-skip gate passes. That keeps genomes with low effective rates from
70
- paying the full operator-selection cost every generation while still letting
71
- successful genomes perform multiple edits once they have been admitted into
72
- the flow.
61
+ Apply an ADD_CONN mutation with reuse and weight nudging.
73
62
 
74
- Each loop iteration captures a before-snapshot, applies one operator,
75
- performs an extra exploration edge when configured, and finally records whether the genome
76
- actually grew. That final feedback is what later allows operator adaptation
77
- and bandit-style policies to reward operators that change structure instead
78
- of merely consuming attempts.
63
+ This is the connection-growth companion to `applyAddNodeMutation()`. The
64
+ structural edit itself is delegated to the reuse-aware connection helper so
65
+ identical edge discoveries can still share innovation identity across the
66
+ population.
79
67
 
80
68
  Parameters:
81
69
  - `genome` - - genome to mutate
82
70
  - `internal` - - neat controller context
83
71
  - `methods` - - mutation methods module
84
72
 
85
- Returns: Promise resolving after mutation attempts complete
73
+ Returns: void
86
74
 
87
- ### initializeAdaptiveMutation
75
+ ### applyAddNodeMutation
88
76
 
89
77
  ```ts
90
- initializeAdaptiveMutation(
78
+ applyAddNodeMutation(
91
79
  genome: GenomeWithMetadata,
92
80
  internal: NeatControllerForMutation,
81
+ methods: { mutation: unknown; },
93
82
  ): void
94
83
  ```
95
84
 
96
- Initialize per-genome adaptive mutation parameters if configured.
97
-
98
- Adaptive mutation is stateful at the genome level, not just a controller
99
- default. This helper assigns the first persistent rate and optional amount so
100
- later generations can treat the genome as carrying its own mutation budget.
85
+ Apply an ADD_NODE mutation with reuse and weight nudging.
101
86
 
102
- The helper only writes when the genome has not yet been initialized. That is
103
- why it runs at the top of `mutateGenome()` on every pass: it behaves like a
104
- cheap bootstrap check rather than a repeated reset of evolved mutation
105
- behavior.
87
+ The add-node path is special because it needs both innovation-aware
88
+ structural growth and a post-split weight nudge that makes the topology
89
+ change observable immediately in downstream behavior and tests. The helper
90
+ intentionally treats cache invalidation as part of the operation rather than
91
+ leaving it to callers.
106
92
 
107
93
  Parameters:
108
- - `genome` - - genome to initialize
94
+ - `genome` - - genome to mutate
109
95
  - `internal` - - neat controller context
96
+ - `methods` - - mutation methods module
110
97
 
111
98
  Returns: void
112
99
 
113
- ### resolveEffectiveRate
100
+ ### applyMutationOperator
114
101
 
115
102
  ```ts
116
- resolveEffectiveRate(
103
+ applyMutationOperator(
117
104
  genome: GenomeWithMetadata,
105
+ mutationMethod: MutationMethod,
118
106
  internal: NeatControllerForMutation,
119
- ): number
107
+ methods: { mutation: unknown; },
108
+ ): void
120
109
  ```
121
110
 
122
- Resolve the effective mutation rate for a genome.
123
-
124
- This helper explains the precedence order for rate policy:
111
+ Apply a mutation operator to a genome and invalidate caches as needed.
125
112
 
126
- 1. an explicit controller-level `mutationRate` wins,
127
- 2. otherwise an adaptive per-genome `_mutRate` is used when adaptive
128
- mutation is enabled,
129
- 3. otherwise the flow falls back to the local default.
113
+ This helper is the dispatch hinge between policy and topology. Structural
114
+ growth operators such as `ADD_NODE` and `ADD_CONN` are routed through the
115
+ innovation-reuse helpers because the controller cares about more than local
116
+ graph edits; it also needs stable innovation history for later crossover and
117
+ speciation.
130
118
 
131
- Keeping that precedence isolated here makes the rest of the mutation flow
132
- read as orchestration instead of configuration branching.
119
+ Non-structural operators stay delegated to the genome's own `mutate()`
120
+ implementation. Cache invalidation is then handled separately so the flow can
121
+ keep the expensive cleanup targeted to methods that plausibly changed the
122
+ structural view of the genome.
133
123
 
134
124
  Parameters:
135
- - `genome` - - genome to resolve for
125
+ - `genome` - - genome to mutate
126
+ - `mutationMethod` - - mutation operator to apply
136
127
  - `internal` - - neat controller context
128
+ - `methods` - - mutation methods module
137
129
 
138
- Returns: effective mutation rate
130
+ Returns: void
139
131
 
140
- ### resolveEffectiveAmount
132
+ ### captureStructuralSizes
141
133
 
142
134
  ```ts
143
- resolveEffectiveAmount(
135
+ captureStructuralSizes(
144
136
  genome: GenomeWithMetadata,
145
- internal: NeatControllerForMutation,
146
- ): number
137
+ ): { beforeNodes: number; beforeConns: number; }
147
138
  ```
148
139
 
149
- Resolve the effective mutation amount for a genome.
140
+ Capture structural sizes used to evaluate operator success.
150
141
 
151
- Mutation amount answers a different question from mutation rate. Rate decides
152
- whether the genome enters the flow. Amount decides how many operator draws it
153
- receives once admitted. When adaptive mutation amount is enabled, the genome
154
- may carry its own evolving attempt budget; otherwise the controller-wide
155
- amount stays authoritative.
142
+ Operator adaptation in this subtree is intentionally coarse-grained: it asks
143
+ whether an attempted mutation increased structural size, not whether the
144
+ resulting genome later scored better. This helper records the pre-mutation
145
+ node and connection counts that make that local success signal possible.
156
146
 
157
147
  Parameters:
158
- - `genome` - - genome to resolve for
159
- - `internal` - - neat controller context
148
+ - `genome` - - genome to inspect
160
149
 
161
- Returns: effective mutation amount
150
+ Returns: structural size snapshot
162
151
 
163
- ### shouldMutateGenome
152
+ ### initializeAdaptiveMutation
164
153
 
165
154
  ```ts
166
- shouldMutateGenome(
167
- effectiveRate: number,
155
+ initializeAdaptiveMutation(
156
+ genome: GenomeWithMetadata,
168
157
  internal: NeatControllerForMutation,
169
- ): boolean
158
+ ): void
170
159
  ```
171
160
 
172
- Decide whether a genome should be mutated based on probability.
161
+ Initialize per-genome adaptive mutation parameters if configured.
173
162
 
174
- This is the narrow admission gate for the per-genome flow. Keeping the RNG
175
- comparison in one helper makes the orchestration read clearly and gives tests
176
- one stable seam for deterministic gating behavior.
163
+ Adaptive mutation is stateful at the genome level, not just a controller
164
+ default. This helper assigns the first persistent rate and optional amount so
165
+ later generations can treat the genome as carrying its own mutation budget.
166
+
167
+ The helper only writes when the genome has not yet been initialized. That is
168
+ why it runs at the top of `mutateGenome()` on every pass: it behaves like a
169
+ cheap bootstrap check rather than a repeated reset of evolved mutation
170
+ behavior.
177
171
 
178
172
  Parameters:
179
- - `effectiveRate` - - effective mutation probability
173
+ - `genome` - - genome to initialize
180
174
  - `internal` - - neat controller context
181
175
 
182
- Returns: true when the genome should be mutated
176
+ Returns: void
183
177
 
184
- ### selectConcreteMutationMethod
178
+ ### maybeAddExtraConnection
185
179
 
186
180
  ```ts
187
- selectConcreteMutationMethod(
181
+ maybeAddExtraConnection(
188
182
  genome: GenomeWithMetadata,
189
183
  internal: NeatControllerForMutation,
190
- ): Promise<MutationMethod | null>
184
+ ): void
191
185
  ```
192
186
 
193
- Select a concrete mutation method, resolving legacy arrays when present.
194
-
195
- The selection boundary may already return one final operator, or it may
196
- return a legacy array-like pool for backward-compatible paths. This helper is
197
- the bridge between that policy layer and the execution layer in `flow/`: it
198
- guarantees the rest of the loop sees either one concrete operator or `null`.
187
+ Optionally add an extra connection to increase exploration.
199
188
 
200
- That normalization keeps `mutateGenome()` focused on lifecycle sequencing
201
- rather than on legacy selection-shape quirks.
189
+ This small post-operator hook gives the controller one extra chance to add
190
+ connectivity after the main mutation has landed. It is intentionally
191
+ probabilistic and lightweight: the flow uses it as a gentle exploration bump,
192
+ not as a second full operator-selection phase.
202
193
 
203
194
  Parameters:
204
- - `genome` - - genome to select for
195
+ - `genome` - - genome to mutate
205
196
  - `internal` - - neat controller context
206
197
 
207
- Returns: resolved mutation method or null
198
+ Returns: void
208
199
 
209
- ### captureStructuralSizes
200
+ ### mutateGenome
210
201
 
211
202
  ```ts
212
- captureStructuralSizes(
203
+ mutateGenome(
213
204
  genome: GenomeWithMetadata,
214
- ): { beforeNodes: number; beforeConns: number; }
205
+ internal: NeatControllerForMutation,
206
+ methods: { mutation: unknown; },
207
+ ): Promise<void>
215
208
  ```
216
209
 
217
- Capture structural sizes used to evaluate operator success.
210
+ Mutate a single genome based on configured mutation policies.
218
211
 
219
- Operator adaptation in this subtree is intentionally coarse-grained: it asks
220
- whether an attempted mutation increased structural size, not whether the
221
- resulting genome later scored better. This helper records the pre-mutation
222
- node and connection counts that make that local success signal possible.
212
+ This is the orchestration entry point for the `flow/` chapter. It keeps the
213
+ per-genome lifecycle linear: adaptive settings are prepared first, then one
214
+ probability gate decides whether work happens at all, and only then does the
215
+ helper loop ask `select/` for concrete operators.
216
+
217
+ The important design choice is that mutation amount is resolved after the
218
+ mutate-or-skip gate passes. That keeps genomes with low effective rates from
219
+ paying the full operator-selection cost every generation while still letting
220
+ successful genomes perform multiple edits once they have been admitted into
221
+ the flow.
222
+
223
+ Each loop iteration captures a before-snapshot, applies one operator,
224
+ performs an extra exploration edge when configured, and finally records whether the genome
225
+ actually grew. That final feedback is what later allows operator adaptation
226
+ and bandit-style policies to reward operators that change structure instead
227
+ of merely consuming attempts.
223
228
 
224
229
  Parameters:
225
- - `genome` - - genome to inspect
230
+ - `genome` - - genome to mutate
231
+ - `internal` - - neat controller context
232
+ - `methods` - - mutation methods module
226
233
 
227
- Returns: structural size snapshot
234
+ Returns: Promise resolving after mutation attempts complete
228
235
 
229
- ### applyMutationOperator
236
+ ### resolveEffectiveAmount
230
237
 
231
238
  ```ts
232
- applyMutationOperator(
239
+ resolveEffectiveAmount(
233
240
  genome: GenomeWithMetadata,
234
- mutationMethod: MutationMethod,
235
241
  internal: NeatControllerForMutation,
236
- methods: { mutation: unknown; },
237
- ): void
242
+ ): number
238
243
  ```
239
244
 
240
- Apply a mutation operator to a genome and invalidate caches as needed.
241
-
242
- This helper is the dispatch hinge between policy and topology. Structural
243
- growth operators such as `ADD_NODE` and `ADD_CONN` are routed through the
244
- innovation-reuse helpers because the controller cares about more than local
245
- graph edits; it also needs stable innovation history for later crossover and
246
- speciation.
245
+ Resolve the effective mutation amount for a genome.
247
246
 
248
- Non-structural operators stay delegated to the genome's own `mutate()`
249
- implementation. Cache invalidation is then handled separately so the flow can
250
- keep the expensive cleanup targeted to methods that plausibly changed the
251
- structural view of the genome.
247
+ Mutation amount answers a different question from mutation rate. Rate decides
248
+ whether the genome enters the flow. Amount decides how many operator draws it
249
+ receives once admitted. When adaptive mutation amount is enabled, the genome
250
+ may carry its own evolving attempt budget; otherwise the controller-wide
251
+ amount stays authoritative.
252
252
 
253
253
  Parameters:
254
- - `genome` - - genome to mutate
255
- - `mutationMethod` - - mutation operator to apply
254
+ - `genome` - - genome to resolve for
256
255
  - `internal` - - neat controller context
257
- - `methods` - - mutation methods module
258
256
 
259
- Returns: void
257
+ Returns: effective mutation amount
260
258
 
261
- ### applyAddNodeMutation
259
+ ### resolveEffectiveRate
262
260
 
263
261
  ```ts
264
- applyAddNodeMutation(
262
+ resolveEffectiveRate(
265
263
  genome: GenomeWithMetadata,
266
264
  internal: NeatControllerForMutation,
267
- methods: { mutation: unknown; },
268
- ): void
265
+ ): number
269
266
  ```
270
267
 
271
- Apply an ADD_NODE mutation with reuse and weight nudging.
268
+ Resolve the effective mutation rate for a genome.
272
269
 
273
- The add-node path is special because it needs both innovation-aware
274
- structural growth and a post-split weight nudge that makes the topology
275
- change observable immediately in downstream behavior and tests. The helper
276
- intentionally treats cache invalidation as part of the operation rather than
277
- leaving it to callers.
270
+ This helper explains the precedence order for rate policy:
271
+
272
+ 1. an explicit controller-level `mutationRate` wins,
273
+ 2. otherwise an adaptive per-genome `_mutRate` is used when adaptive
274
+ mutation is enabled,
275
+ 3. otherwise the flow falls back to the local default.
276
+
277
+ Keeping that precedence isolated here makes the rest of the mutation flow
278
+ read as orchestration instead of configuration branching.
278
279
 
279
280
  Parameters:
280
- - `genome` - - genome to mutate
281
+ - `genome` - - genome to resolve for
281
282
  - `internal` - - neat controller context
282
- - `methods` - - mutation methods module
283
283
 
284
- Returns: void
284
+ Returns: effective mutation rate
285
285
 
286
- ### applyAddConnMutation
286
+ ### selectConcreteMutationMethod
287
287
 
288
288
  ```ts
289
- applyAddConnMutation(
289
+ selectConcreteMutationMethod(
290
290
  genome: GenomeWithMetadata,
291
291
  internal: NeatControllerForMutation,
292
- methods: { mutation: unknown; },
293
- ): void
292
+ ): Promise<MutationMethod | null>
294
293
  ```
295
294
 
296
- Apply an ADD_CONN mutation with reuse and weight nudging.
295
+ Select a concrete mutation method, resolving legacy arrays when present.
297
296
 
298
- This is the connection-growth companion to `applyAddNodeMutation()`. The
299
- structural edit itself is delegated to the reuse-aware connection helper so
300
- identical edge discoveries can still share innovation identity across the
301
- population.
297
+ The selection boundary may already return one final operator, or it may
298
+ return a legacy array-like pool for backward-compatible paths. This helper is
299
+ the bridge between that policy layer and the execution layer in `flow/`: it
300
+ guarantees the rest of the loop sees either one concrete operator or `null`.
301
+
302
+ That normalization keeps `mutateGenome()` focused on lifecycle sequencing
303
+ rather than on legacy selection-shape quirks.
302
304
 
303
305
  Parameters:
304
- - `genome` - - genome to mutate
306
+ - `genome` - - genome to select for
305
307
  - `internal` - - neat controller context
306
- - `methods` - - mutation methods module
307
308
 
308
- Returns: void
309
+ Returns: resolved mutation method or null
309
310
 
310
311
  ### shouldInvalidateCaches
311
312
 
@@ -329,27 +330,26 @@ Parameters:
329
330
 
330
331
  Returns: true when caches should be invalidated
331
332
 
332
- ### maybeAddExtraConnection
333
+ ### shouldMutateGenome
333
334
 
334
335
  ```ts
335
- maybeAddExtraConnection(
336
- genome: GenomeWithMetadata,
336
+ shouldMutateGenome(
337
+ effectiveRate: number,
337
338
  internal: NeatControllerForMutation,
338
- ): void
339
+ ): boolean
339
340
  ```
340
341
 
341
- Optionally add an extra connection to increase exploration.
342
+ Decide whether a genome should be mutated based on probability.
342
343
 
343
- This small post-operator hook gives the controller one extra chance to add
344
- connectivity after the main mutation has landed. It is intentionally
345
- probabilistic and lightweight: the flow uses it as a gentle exploration bump,
346
- not as a second full operator-selection phase.
344
+ This is the narrow admission gate for the per-genome flow. Keeping the RNG
345
+ comparison in one helper makes the orchestration read clearly and gives tests
346
+ one stable seam for deterministic gating behavior.
347
347
 
348
348
  Parameters:
349
- - `genome` - - genome to mutate
349
+ - `effectiveRate` - - effective mutation probability
350
350
  - `internal` - - neat controller context
351
351
 
352
- Returns: void
352
+ Returns: true when the genome should be mutated
353
353
 
354
354
  ### updateOperatorStatsIfNeeded
355
355