@reicek/neataptic-ts 0.1.25 → 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 (210) 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/package.json +19 -13
  8. package/plans/Flappy_Bird_Folder_Documentation_Pass.md +4 -4
  9. package/plans/README.md +24 -0
  10. package/plans/Roadmap.md +62 -40
  11. package/plans/analyze-trace-solid-split.plans.md +66 -0
  12. package/plans/architecture-solid-split.plans.md +9 -15
  13. package/plans/asciiMaze-typescript-repair.plans.md +1 -1
  14. package/plans/generate-docs-solid-split.plans.md +87 -0
  15. package/plans/methods-docs.plans.md +25 -1
  16. package/plans/methods-solid-split.plans.md +14 -14
  17. package/plans/neat-docs.plans.md +9 -1
  18. package/plans/neat-test-surface-repair.plans.md +1 -1
  19. package/plans/render-docs-html-solid-split.plans.md +68 -0
  20. package/plans/src-no-explicit-any-cleanup.plans.md +1 -1
  21. package/plans/utils-docs.plans.md +6 -1
  22. package/scripts/analyze-trace/analyze-trace.analysis.ts +479 -0
  23. package/scripts/analyze-trace/analyze-trace.constants.ts +35 -0
  24. package/scripts/analyze-trace/analyze-trace.io.ts +69 -0
  25. package/scripts/analyze-trace/analyze-trace.report.ts +100 -0
  26. package/scripts/analyze-trace/analyze-trace.shared.ts +116 -0
  27. package/scripts/analyze-trace/analyze-trace.ts +45 -0
  28. package/scripts/analyze-trace/analyze-trace.types.ts +72 -0
  29. package/scripts/assets/theme.css +80 -23
  30. package/scripts/copy-examples.ts +239 -0
  31. package/scripts/export-onnx.ts +223 -0
  32. package/scripts/generate-bench-tables.ts +378 -37
  33. package/scripts/generate-docs/generate-docs.constants.ts +107 -0
  34. package/scripts/generate-docs/generate-docs.order.ts +355 -0
  35. package/scripts/generate-docs/generate-docs.state.ts +31 -0
  36. package/scripts/generate-docs/generate-docs.targets.ts +165 -0
  37. package/scripts/generate-docs/generate-docs.ts +63 -0
  38. package/scripts/generate-docs/generate-docs.types.ts +112 -0
  39. package/scripts/generate-docs/output/generate-docs.output.folder-index.utils.ts +167 -0
  40. package/scripts/generate-docs/output/generate-docs.output.ordering.utils.ts +353 -0
  41. package/scripts/generate-docs/output/generate-docs.output.readme.utils.ts +420 -0
  42. package/scripts/generate-docs/output/generate-docs.output.ts +123 -0
  43. package/scripts/generate-docs/output/generate-docs.output.warnings.utils.ts +219 -0
  44. package/scripts/generate-docs/symbols/generate-docs.symbols.collection.utils.ts +365 -0
  45. package/scripts/generate-docs/symbols/generate-docs.symbols.jsdoc.utils.ts +373 -0
  46. package/scripts/generate-docs/symbols/generate-docs.symbols.normalize.utils.ts +155 -0
  47. package/scripts/generate-docs/symbols/generate-docs.symbols.render.utils.ts +149 -0
  48. package/scripts/generate-docs/symbols/generate-docs.symbols.signature.utils.ts +289 -0
  49. package/scripts/generate-docs/symbols/generate-docs.symbols.ts +11 -0
  50. package/scripts/mermaid-cli.mjs +102 -22
  51. package/scripts/mermaid-cli.ts +736 -0
  52. package/scripts/render-docs-html/render-docs-html.assets.ts +54 -0
  53. package/scripts/render-docs-html/render-docs-html.mermaid.ts +245 -0
  54. package/scripts/{render-docs-html.sidebar.ts → render-docs-html/render-docs-html.navigation.ts} +141 -144
  55. package/scripts/render-docs-html/render-docs-html.pages.ts +333 -0
  56. package/scripts/render-docs-html/render-docs-html.shared.ts +333 -0
  57. package/scripts/render-docs-html/render-docs-html.types.ts +42 -0
  58. package/scripts/render-docs-html.ts +23 -587
  59. package/scripts/run-docs.ts +238 -0
  60. package/scripts/write-dist-docs-pkg.ts +40 -0
  61. package/src/README.md +75 -75
  62. package/src/architecture/connection/README.md +5 -5
  63. package/src/architecture/layer/README.md +508 -508
  64. package/src/architecture/network/README.md +1458 -1458
  65. package/src/architecture/network/activate/README.md +694 -694
  66. package/src/architecture/network/bootstrap/README.md +77 -77
  67. package/src/architecture/network/connect/README.md +74 -74
  68. package/src/architecture/network/deterministic/README.md +135 -135
  69. package/src/architecture/network/evolve/README.md +364 -364
  70. package/src/architecture/network/gating/README.md +130 -130
  71. package/src/architecture/network/genetic/README.md +399 -399
  72. package/src/architecture/network/mutate/README.md +897 -897
  73. package/src/architecture/network/onnx/README.md +720 -720
  74. package/src/architecture/network/onnx/export/README.md +728 -728
  75. package/src/architecture/network/onnx/export/layers/README.md +450 -450
  76. package/src/architecture/network/onnx/import/README.md +618 -618
  77. package/src/architecture/network/onnx/schema/README.md +32 -32
  78. package/src/architecture/network/prune/README.md +245 -245
  79. package/src/architecture/network/remove/README.md +135 -135
  80. package/src/architecture/network/runtime/README.md +106 -106
  81. package/src/architecture/network/serialize/README.md +542 -542
  82. package/src/architecture/network/slab/README.md +608 -608
  83. package/src/architecture/network/standalone/README.md +212 -212
  84. package/src/architecture/network/stats/README.md +84 -84
  85. package/src/architecture/network/topology/README.md +465 -465
  86. package/src/architecture/network/training/README.md +200 -200
  87. package/src/architecture/node/README.md +5 -5
  88. package/src/architecture/nodePool/README.md +14 -14
  89. package/src/methods/README.md +99 -99
  90. package/src/methods/activation/README.md +189 -189
  91. package/src/methods/cost/README.md +131 -131
  92. package/src/methods/rate/README.md +86 -86
  93. package/src/multithreading/README.md +77 -77
  94. package/src/multithreading/workers/browser/README.md +8 -8
  95. package/src/multithreading/workers/node/README.md +8 -8
  96. package/src/neat/README.md +148 -148
  97. package/src/neat/adaptive/README.md +120 -120
  98. package/src/neat/adaptive/acceptance/README.md +40 -40
  99. package/src/neat/adaptive/complexity/README.md +137 -137
  100. package/src/neat/adaptive/core/README.md +197 -197
  101. package/src/neat/adaptive/lineage/README.md +90 -90
  102. package/src/neat/adaptive/mutation/README.md +284 -284
  103. package/src/neat/compat/README.md +43 -43
  104. package/src/neat/compat/core/README.md +90 -90
  105. package/src/neat/diversity/README.md +35 -35
  106. package/src/neat/diversity/core/README.md +88 -88
  107. package/src/neat/evaluate/README.md +85 -85
  108. package/src/neat/evaluate/auto-distance/README.md +75 -75
  109. package/src/neat/evaluate/entropy-compat/README.md +37 -37
  110. package/src/neat/evaluate/entropy-sharing/README.md +43 -43
  111. package/src/neat/evaluate/fitness/README.md +23 -23
  112. package/src/neat/evaluate/novelty/README.md +120 -120
  113. package/src/neat/evaluate/objectives/README.md +17 -17
  114. package/src/neat/evaluate/shared/README.md +94 -94
  115. package/src/neat/evolve/README.md +96 -96
  116. package/src/neat/evolve/adaptive/README.md +60 -60
  117. package/src/neat/evolve/objectives/README.md +63 -63
  118. package/src/neat/evolve/offspring/README.md +56 -56
  119. package/src/neat/evolve/population/README.md +171 -171
  120. package/src/neat/evolve/runtime/README.md +79 -79
  121. package/src/neat/evolve/speciation/README.md +74 -74
  122. package/src/neat/evolve/warnings/README.md +10 -10
  123. package/src/neat/export/README.md +114 -114
  124. package/src/neat/helpers/README.md +50 -50
  125. package/src/neat/init/README.md +9 -9
  126. package/src/neat/lineage/core/README.md +101 -101
  127. package/src/neat/multiobjective/category/README.md +74 -74
  128. package/src/neat/multiobjective/crowding/README.md +272 -272
  129. package/src/neat/multiobjective/dominance/README.md +171 -171
  130. package/src/neat/multiobjective/fronts/README.md +68 -68
  131. package/src/neat/multiobjective/metrics/README.md +43 -43
  132. package/src/neat/multiobjective/objectives/README.md +31 -31
  133. package/src/neat/multiobjective/shared/README.md +27 -27
  134. package/src/neat/mutation/README.md +97 -97
  135. package/src/neat/mutation/add-conn/README.md +115 -115
  136. package/src/neat/mutation/add-node/README.md +126 -126
  137. package/src/neat/mutation/flow/README.md +149 -149
  138. package/src/neat/mutation/repair/README.md +185 -185
  139. package/src/neat/mutation/select/README.md +117 -117
  140. package/src/neat/mutation/shared/README.md +32 -32
  141. package/src/neat/objectives/README.md +25 -25
  142. package/src/neat/objectives/core/README.md +67 -67
  143. package/src/neat/pruning/README.md +40 -40
  144. package/src/neat/pruning/core/README.md +171 -171
  145. package/src/neat/pruning/facade/README.md +32 -32
  146. package/src/neat/rng/README.md +104 -104
  147. package/src/neat/rng/core/README.md +137 -137
  148. package/src/neat/rng/facade/README.md +50 -50
  149. package/src/neat/selection/README.md +111 -111
  150. package/src/neat/selection/core/README.md +227 -227
  151. package/src/neat/selection/facade/README.md +61 -61
  152. package/src/neat/shared/README.md +163 -163
  153. package/src/neat/speciation/README.md +31 -31
  154. package/src/neat/speciation/threshold/README.md +35 -35
  155. package/src/neat/species/README.md +25 -25
  156. package/src/neat/species/core/README.md +20 -20
  157. package/src/neat/species/core/shared/README.md +18 -18
  158. package/src/neat/species/history/context/README.md +22 -22
  159. package/src/neat/telemetry/accessors/README.md +58 -58
  160. package/src/neat/telemetry/exports/README.md +233 -233
  161. package/src/neat/telemetry/facade/README.md +252 -252
  162. package/src/neat/telemetry/facade/archive/README.md +57 -57
  163. package/src/neat/telemetry/facade/buffer/README.md +43 -43
  164. package/src/neat/telemetry/facade/lineage/README.md +12 -12
  165. package/src/neat/telemetry/facade/objectives/README.md +44 -44
  166. package/src/neat/telemetry/facade/runtime/README.md +26 -26
  167. package/src/neat/telemetry/facade/species/README.md +27 -27
  168. package/src/neat/telemetry/metrics/README.md +696 -696
  169. package/src/neat/telemetry/recorder/README.md +57 -57
  170. package/src/neat/telemetry/types/README.md +32 -32
  171. package/src/neat/topology-intent/README.md +75 -75
  172. package/src/utils/README.md +193 -193
  173. package/test/examples/asciiMaze/browser-entry/README.md +92 -92
  174. package/test/examples/asciiMaze/dashboardManager/README.md +109 -109
  175. package/test/examples/asciiMaze/dashboardManager/telemetry/README.md +28 -28
  176. package/test/examples/asciiMaze/evolutionEngine/README.md +1527 -1527
  177. package/test/examples/asciiMaze/mazeMovement/README.md +105 -105
  178. package/test/examples/asciiMaze/mazeMovement/finalization/README.md +16 -16
  179. package/test/examples/asciiMaze/mazeMovement/policy/README.md +57 -57
  180. package/test/examples/asciiMaze/mazeMovement/runtime/README.md +52 -52
  181. package/test/examples/asciiMaze/mazeMovement/shaping/README.md +46 -46
  182. package/test/examples/flappy_bird/browser-entry/README.md +508 -508
  183. package/test/examples/flappy_bird/browser-entry/host/README.md +101 -101
  184. package/test/examples/flappy_bird/browser-entry/host/resize/README.md +144 -144
  185. package/test/examples/flappy_bird/browser-entry/network-view/README.md +194 -194
  186. package/test/examples/flappy_bird/browser-entry/playback/README.md +278 -278
  187. package/test/examples/flappy_bird/browser-entry/playback/background/README.md +129 -129
  188. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/README.md +502 -502
  189. package/test/examples/flappy_bird/browser-entry/playback/frame-render/README.md +139 -139
  190. package/test/examples/flappy_bird/browser-entry/playback/snapshot/README.md +10 -10
  191. package/test/examples/flappy_bird/browser-entry/playback/trail/README.md +43 -43
  192. package/test/examples/flappy_bird/browser-entry/playback/worker-channel/README.md +30 -30
  193. package/test/examples/flappy_bird/browser-entry/runtime/README.md +59 -59
  194. package/test/examples/flappy_bird/browser-entry/visualization/README.md +276 -276
  195. package/test/examples/flappy_bird/browser-entry/worker-channel/README.md +16 -16
  196. package/test/examples/flappy_bird/constants/README.md +1070 -1070
  197. package/test/examples/flappy_bird/environment/README.md +22 -22
  198. package/test/examples/flappy_bird/evaluation/README.md +32 -32
  199. package/test/examples/flappy_bird/evaluation/rollout/README.md +141 -141
  200. package/test/examples/flappy_bird/flappy-evolution-worker/README.md +425 -425
  201. package/test/examples/flappy_bird/simulation-shared/README.md +170 -170
  202. package/test/examples/flappy_bird/simulation-shared/observation/README.md +109 -109
  203. package/test/examples/flappy_bird/trainer/README.md +325 -325
  204. package/test/examples/flappy_bird/trainer/evaluation/README.md +74 -74
  205. package/scripts/analyze-trace.ts +0 -590
  206. package/scripts/copy-examples.mjs +0 -114
  207. package/scripts/export-onnx.mjs +0 -86
  208. package/scripts/generate-bench-tables.mjs +0 -182
  209. package/scripts/generate-docs.ts +0 -2900
  210. package/scripts/write-dist-docs-pkg.mjs +0 -16
@@ -70,77 +70,100 @@ flowchart LR
70
70
 
71
71
  ## neat/evolve/population/evolve.population.utils.ts
72
72
 
73
- ### buildNextPopulation
73
+ ### addOffspring
74
74
 
75
75
  ```ts
76
- buildNextPopulation(
76
+ addOffspring(
77
77
  internal: NeatControllerForEvolution,
78
- helpers: { applyElitism: (nextPopulation: default[]) => void; applyProvenance: (nextPopulation: default[]) => void; addOffspring: (nextPopulation: default[]) => Promise<void>; },
79
- ): Promise<default[]>
78
+ nextPopulation: default[],
79
+ helpers: { addSpeciatedOffspring: (nextPopulation: default[], remainingSlots: number) => Promise<void>; addUnspeciatedOffspring: (nextPopulation: default[], remainingSlots: number) => Promise<void>; },
80
+ ): Promise<void>
80
81
  ```
81
82
 
82
- Build the next population (elitism, provenance, offspring).
83
+ Add offspring to fill remaining population slots.
83
84
 
84
- This helper is the orchestration entrypoint for next-generation assembly.
85
- It deliberately reads like a short collect-and-fill pipeline: start with an
86
- empty container, reserve the slots that should bypass parent selection, then
87
- spend the remaining capacity on offspring generation. The mutation and prune
88
- phases happen later; this boundary only answers how the raw next population is
89
- assembled before those later transforms run.
85
+ This helper spends whatever population budget remains after elitism and
86
+ provenance have claimed their slots. Its main job is not to create children
87
+ itself, but to choose the correct filling strategy: species-aware allocation
88
+ when the controller currently maintains a species registry, or global parent
89
+ selection when it does not.
90
90
 
91
- Pedagogically, this is the chapter's "packing list" helper. It does not yet
92
- ask whether the chosen genomes are structurally clean enough for the next
93
- loop. It only decides which genomes enter the first draft of the next
94
- population, and in which order those admission rules are applied.
91
+ That branch is the main conceptual seam in the chapter. Everything before
92
+ this point is deterministic packing. This helper is where the controller asks
93
+ whether the remaining search budget should respect live species boundaries or
94
+ whether it should fall back to one global parent pool.
95
95
 
96
- Example:
96
+ Parameters:
97
+ - `internal` - - NEAT controller instance.
98
+ - `nextPopulation` - - Target population array.
99
+ - `helpers` - - Helper callbacks for offspring selection.
100
+ - `helpers` - - Speciated offspring helper.
101
+ - `helpers` - - Unspeciated offspring helper.
102
+
103
+ Returns: A promise that resolves after the remaining population budget is filled.
104
+
105
+ ### addSpeciatedOffspring
97
106
 
98
107
  ```ts
99
- const nextPopulation = await buildNextPopulation(internal, {
100
- applyElitism: (population) => applyElitism(internal, population),
101
- applyProvenance: (population) => applyProvenance(internal, population),
102
- addOffspring: (population) => addOffspring(internal, population, helpers),
103
- });
108
+ addSpeciatedOffspring(
109
+ internal: NeatControllerForEvolution,
110
+ nextPopulation: default[],
111
+ remainingSlots: number,
112
+ config: { minOffspringDefault: number; survivalThresholdDefault: number; youngThresholdDefault: number; youngMultiplierDefault: number; oldThresholdDefault: number; oldMultiplierDefault: number; crossSpeciesGuardLimit: number; },
113
+ ): Promise<void>
104
114
  ```
105
115
 
116
+ Add offspring when speciation is enabled.
117
+
118
+ This is the species-aware branch of population filling. It converts the
119
+ remaining population budget into per-species child counts, records those
120
+ counts for later telemetry or diagnostics reads, then breeds within each
121
+ species using the narrower offspring mechanics described in `offspring/`.
122
+
123
+ The helper stays intentionally focused on allocation and local survivor
124
+ pools. It does not re-run speciation or mutate the produced children.
125
+
126
+ The important teaching split is that this helper does two different jobs in
127
+ sequence:
128
+
129
+ 1. decide how much reproductive budget each species deserves,
130
+ 2. spend each species-local budget through survivor-based crossover.
131
+
132
+ Keeping those jobs together makes the generated chapter longer, but it also
133
+ keeps the species-aware branch readable in one place instead of scattering the
134
+ allocation rationale across several tiny helpers.
135
+
106
136
  Parameters:
107
137
  - `internal` - - NEAT controller instance.
108
- - `helpers` - - Helper callbacks for population construction.
109
- - `helpers` - - Elitism helper.
110
- - `helpers` - - Provenance helper.
111
- - `helpers` - - Offspring helper.
138
+ - `nextPopulation` - - Target population array.
139
+ - `remainingSlots` - - Slots remaining to fill.
140
+ - `config` - - Offspring allocation constants.
112
141
 
113
- Returns: Next population array before later mutation and pruning phases.
142
+ Returns: A promise that resolves after species-aware offspring have been added.
114
143
 
115
- ### enforcePopulationConstraints
144
+ ### addUnspeciatedOffspring
116
145
 
117
146
  ```ts
118
- enforcePopulationConstraints(
147
+ addUnspeciatedOffspring(
119
148
  internal: NeatControllerForEvolution,
120
149
  nextPopulation: default[],
150
+ remainingSlots: number,
121
151
  ): Promise<void>
122
152
  ```
123
153
 
124
- Ensure new population meets structural constraints.
125
-
126
- Population assembly intentionally separates slot-filling from structural
127
- cleanup. Elites may already be valid, provenance genomes may come from a
128
- seed network or a fresh constructor path, and offspring may arrive from
129
- crossover with small topology issues that the controller routinely repairs.
130
- Running those repairs here keeps later evolve code free to assume the new
131
- population already satisfies the controller's minimum hidden-node and
132
- dead-end expectations.
154
+ Add offspring when speciation is disabled.
133
155
 
134
- Keeping this repair pass at the end is a deliberate architecture choice. If
135
- every earlier helper tried to repair genomes inline, the chapter would blur
136
- slot-allocation policy together with structural-safety policy. Centralizing
137
- cleanup here keeps the earlier helpers focused on population composition.
156
+ When no species registry is active, the population builder falls back to the
157
+ controller's global offspring-selection path. This keeps the no-speciation
158
+ branch small and makes the contrast with the species-aware allocator easy to
159
+ read in the generated chapter.
138
160
 
139
161
  Parameters:
140
162
  - `internal` - - NEAT controller instance.
141
- - `nextPopulation` - - Population to validate.
163
+ - `nextPopulation` - - Target population array.
164
+ - `remainingSlots` - - Slots remaining to fill.
142
165
 
143
- Returns: A promise that resolves after best-effort structural cleanup.
166
+ Returns: A promise that resolves after all remaining slots have been filled.
144
167
 
145
168
  ### applyElitism
146
169
 
@@ -194,100 +217,82 @@ Parameters:
194
217
 
195
218
  Returns: Nothing.
196
219
 
197
- ### addOffspring
220
+ ### buildNextPopulation
198
221
 
199
222
  ```ts
200
- addOffspring(
223
+ buildNextPopulation(
201
224
  internal: NeatControllerForEvolution,
202
- nextPopulation: default[],
203
- helpers: { addSpeciatedOffspring: (nextPopulation: default[], remainingSlots: number) => Promise<void>; addUnspeciatedOffspring: (nextPopulation: default[], remainingSlots: number) => Promise<void>; },
204
- ): Promise<void>
225
+ helpers: { applyElitism: (nextPopulation: default[]) => void; applyProvenance: (nextPopulation: default[]) => void; addOffspring: (nextPopulation: default[]) => Promise<void>; },
226
+ ): Promise<default[]>
205
227
  ```
206
228
 
207
- Add offspring to fill remaining population slots.
208
-
209
- This helper spends whatever population budget remains after elitism and
210
- provenance have claimed their slots. Its main job is not to create children
211
- itself, but to choose the correct filling strategy: species-aware allocation
212
- when the controller currently maintains a species registry, or global parent
213
- selection when it does not.
214
-
215
- That branch is the main conceptual seam in the chapter. Everything before
216
- this point is deterministic packing. This helper is where the controller asks
217
- whether the remaining search budget should respect live species boundaries or
218
- whether it should fall back to one global parent pool.
229
+ Build the next population (elitism, provenance, offspring).
219
230
 
220
- Parameters:
221
- - `internal` - - NEAT controller instance.
222
- - `nextPopulation` - - Target population array.
223
- - `helpers` - - Helper callbacks for offspring selection.
224
- - `helpers` - - Speciated offspring helper.
225
- - `helpers` - - Unspeciated offspring helper.
231
+ This helper is the orchestration entrypoint for next-generation assembly.
232
+ It deliberately reads like a short collect-and-fill pipeline: start with an
233
+ empty container, reserve the slots that should bypass parent selection, then
234
+ spend the remaining capacity on offspring generation. The mutation and prune
235
+ phases happen later; this boundary only answers how the raw next population is
236
+ assembled before those later transforms run.
226
237
 
227
- Returns: A promise that resolves after the remaining population budget is filled.
238
+ Pedagogically, this is the chapter's "packing list" helper. It does not yet
239
+ ask whether the chosen genomes are structurally clean enough for the next
240
+ loop. It only decides which genomes enter the first draft of the next
241
+ population, and in which order those admission rules are applied.
228
242
 
229
- ### addSpeciatedOffspring
243
+ Example:
230
244
 
231
245
  ```ts
232
- addSpeciatedOffspring(
233
- internal: NeatControllerForEvolution,
234
- nextPopulation: default[],
235
- remainingSlots: number,
236
- config: { minOffspringDefault: number; survivalThresholdDefault: number; youngThresholdDefault: number; youngMultiplierDefault: number; oldThresholdDefault: number; oldMultiplierDefault: number; crossSpeciesGuardLimit: number; },
237
- ): Promise<void>
246
+ const nextPopulation = await buildNextPopulation(internal, {
247
+ applyElitism: (population) => applyElitism(internal, population),
248
+ applyProvenance: (population) => applyProvenance(internal, population),
249
+ addOffspring: (population) => addOffspring(internal, population, helpers),
250
+ });
238
251
  ```
239
252
 
240
- Add offspring when speciation is enabled.
241
-
242
- This is the species-aware branch of population filling. It converts the
243
- remaining population budget into per-species child counts, records those
244
- counts for later telemetry or diagnostics reads, then breeds within each
245
- species using the narrower offspring mechanics described in `offspring/`.
246
-
247
- The helper stays intentionally focused on allocation and local survivor
248
- pools. It does not re-run speciation or mutate the produced children.
249
-
250
- The important teaching split is that this helper does two different jobs in
251
- sequence:
252
-
253
- 1. decide how much reproductive budget each species deserves,
254
- 2. spend each species-local budget through survivor-based crossover.
255
-
256
- Keeping those jobs together makes the generated chapter longer, but it also
257
- keeps the species-aware branch readable in one place instead of scattering the
258
- allocation rationale across several tiny helpers.
259
-
260
253
  Parameters:
261
254
  - `internal` - - NEAT controller instance.
262
- - `nextPopulation` - - Target population array.
263
- - `remainingSlots` - - Slots remaining to fill.
264
- - `config` - - Offspring allocation constants.
255
+ - `helpers` - - Helper callbacks for population construction.
256
+ - `helpers` - - Elitism helper.
257
+ - `helpers` - - Provenance helper.
258
+ - `helpers` - - Offspring helper.
265
259
 
266
- Returns: A promise that resolves after species-aware offspring have been added.
260
+ Returns: Next population array before later mutation and pruning phases.
267
261
 
268
- ### addUnspeciatedOffspring
262
+ ### buildSpeciesOffspring
269
263
 
270
264
  ```ts
271
- addUnspeciatedOffspring(
265
+ buildSpeciesOffspring(
272
266
  internal: NeatControllerForEvolution,
273
- nextPopulation: default[],
274
- remainingSlots: number,
275
- ): Promise<void>
267
+ survivors: GenomeWithMetadata[],
268
+ speciesIndex: number,
269
+ crossSpeciesProbability: number,
270
+ crossSpeciesGuardLimit: number,
271
+ survivalThresholdDefault: number,
272
+ ): GenomeWithMetadata
276
273
  ```
277
274
 
278
- Add offspring when speciation is disabled.
275
+ Build a single offspring within a species.
279
276
 
280
- When no species registry is active, the population builder falls back to the
281
- controller's global offspring-selection path. This keeps the no-speciation
282
- branch small and makes the contrast with the species-aware allocator easy to
283
- read in the generated chapter.
277
+ This helper is the point where species-local survivor selection turns into
278
+ one actual child. It chooses both parents, performs crossover, and annotates
279
+ runtime lineage metadata so the resulting genome is ready for later telemetry,
280
+ lineage, and inbreeding reads.
281
+
282
+ Conceptually, this is where the abstract allocation budget becomes one real
283
+ experiment. Everything above this helper is still about counts and survivor
284
+ pools; this helper is where the controller finally spends one unit of that
285
+ budget on one concrete child genome.
284
286
 
285
287
  Parameters:
286
288
  - `internal` - - NEAT controller instance.
287
- - `nextPopulation` - - Target population array.
288
- - `remainingSlots` - - Slots remaining to fill.
289
+ - `survivors` - - Survivors pool for selection.
290
+ - `speciesIndex` - - Species index.
291
+ - `crossSpeciesProbability` - - Cross-species mating probability.
292
+ - `crossSpeciesGuardLimit` - - Retry guard for cross-species selection.
293
+ - `survivalThresholdDefault` - - Default survivor-window policy used when cross-species selection samples another species.
289
294
 
290
- Returns: A promise that resolves after all remaining slots have been filled.
295
+ Returns: Offspring genome carrying runtime metadata.
291
296
 
292
297
  ### computeOffspringAllocation
293
298
 
@@ -322,34 +327,6 @@ Parameters:
322
327
 
323
328
  Returns: Offspring allocation per species index.
324
329
 
325
- ### enforceMinimumOffspring
326
-
327
- ```ts
328
- enforceMinimumOffspring(
329
- internal: NeatControllerForEvolution,
330
- allocation: number[],
331
- remainingSlots: number,
332
- minOffspringDefault: number,
333
- ): void
334
- ```
335
-
336
- Enforce minimum offspring per species when possible.
337
-
338
- This rule prevents species allocation from collapsing entirely onto a few
339
- dominant lineages when the remaining slot budget is large enough to preserve
340
- a broader search frontier.
341
-
342
- In other words, this is the chapter's anti-monoculture guard. It only runs
343
- when the slot budget is big enough to afford that diversity protection.
344
-
345
- Parameters:
346
- - `internal` - - NEAT controller instance.
347
- - `allocation` - - Allocation array to adjust.
348
- - `remainingSlots` - - Total slots available.
349
- - `minOffspringDefault` - - Default minimum offspring.
350
-
351
- Returns: Nothing.
352
-
353
330
  ### distributeRemainingSlots
354
331
 
355
332
  ```ts
@@ -377,10 +354,10 @@ Parameters:
377
354
 
378
355
  Returns: Nothing.
379
356
 
380
- ### trimOversubscription
357
+ ### enforceMinimumOffspring
381
358
 
382
359
  ```ts
383
- trimOversubscription(
360
+ enforceMinimumOffspring(
384
361
  internal: NeatControllerForEvolution,
385
362
  allocation: number[],
386
363
  remainingSlots: number,
@@ -388,15 +365,14 @@ trimOversubscription(
388
365
  ): void
389
366
  ```
390
367
 
391
- Trim allocations when oversubscribed.
368
+ Enforce minimum offspring per species when possible.
392
369
 
393
- Minimum-offspring guarantees can occasionally oversubscribe the remaining
394
- budget. This helper trims from the largest allocations first while still
395
- respecting the minimum line preserved for each surviving species.
370
+ This rule prevents species allocation from collapsing entirely onto a few
371
+ dominant lineages when the remaining slot budget is large enough to preserve
372
+ a broader search frontier.
396
373
 
397
- Read it as the final safety rail after the diversity protections have done
398
- their work. The helper is not changing the policy goal; it is only forcing
399
- the final integer allocation back inside the available slot budget.
374
+ In other words, this is the chapter's anti-monoculture guard. It only runs
375
+ when the slot budget is big enough to afford that diversity protection.
400
376
 
401
377
  Parameters:
402
378
  - `internal` - - NEAT controller instance.
@@ -406,40 +382,35 @@ Parameters:
406
382
 
407
383
  Returns: Nothing.
408
384
 
409
- ### buildSpeciesOffspring
385
+ ### enforcePopulationConstraints
410
386
 
411
387
  ```ts
412
- buildSpeciesOffspring(
388
+ enforcePopulationConstraints(
413
389
  internal: NeatControllerForEvolution,
414
- survivors: GenomeWithMetadata[],
415
- speciesIndex: number,
416
- crossSpeciesProbability: number,
417
- crossSpeciesGuardLimit: number,
418
- survivalThresholdDefault: number,
419
- ): GenomeWithMetadata
390
+ nextPopulation: default[],
391
+ ): Promise<void>
420
392
  ```
421
393
 
422
- Build a single offspring within a species.
394
+ Ensure new population meets structural constraints.
423
395
 
424
- This helper is the point where species-local survivor selection turns into
425
- one actual child. It chooses both parents, performs crossover, and annotates
426
- runtime lineage metadata so the resulting genome is ready for later telemetry,
427
- lineage, and inbreeding reads.
396
+ Population assembly intentionally separates slot-filling from structural
397
+ cleanup. Elites may already be valid, provenance genomes may come from a
398
+ seed network or a fresh constructor path, and offspring may arrive from
399
+ crossover with small topology issues that the controller routinely repairs.
400
+ Running those repairs here keeps later evolve code free to assume the new
401
+ population already satisfies the controller's minimum hidden-node and
402
+ dead-end expectations.
428
403
 
429
- Conceptually, this is where the abstract allocation budget becomes one real
430
- experiment. Everything above this helper is still about counts and survivor
431
- pools; this helper is where the controller finally spends one unit of that
432
- budget on one concrete child genome.
404
+ Keeping this repair pass at the end is a deliberate architecture choice. If
405
+ every earlier helper tried to repair genomes inline, the chapter would blur
406
+ slot-allocation policy together with structural-safety policy. Centralizing
407
+ cleanup here keeps the earlier helpers focused on population composition.
433
408
 
434
409
  Parameters:
435
410
  - `internal` - - NEAT controller instance.
436
- - `survivors` - - Survivors pool for selection.
437
- - `speciesIndex` - - Species index.
438
- - `crossSpeciesProbability` - - Cross-species mating probability.
439
- - `crossSpeciesGuardLimit` - - Retry guard for cross-species selection.
440
- - `survivalThresholdDefault` - - Default survivor-window policy used when cross-species selection samples another species.
411
+ - `nextPopulation` - - Population to validate.
441
412
 
442
- Returns: Offspring genome carrying runtime metadata.
413
+ Returns: A promise that resolves after best-effort structural cleanup.
443
414
 
444
415
  ### selectSecondParent
445
416
 
@@ -475,3 +446,32 @@ Parameters:
475
446
  - `survivalThresholdDefault` - - Default survivor-window policy used when sampling another species.
476
447
 
477
448
  Returns: Chosen parent genome from the current or another species.
449
+
450
+ ### trimOversubscription
451
+
452
+ ```ts
453
+ trimOversubscription(
454
+ internal: NeatControllerForEvolution,
455
+ allocation: number[],
456
+ remainingSlots: number,
457
+ minOffspringDefault: number,
458
+ ): void
459
+ ```
460
+
461
+ Trim allocations when oversubscribed.
462
+
463
+ Minimum-offspring guarantees can occasionally oversubscribe the remaining
464
+ budget. This helper trims from the largest allocations first while still
465
+ respecting the minimum line preserved for each surviving species.
466
+
467
+ Read it as the final safety rail after the diversity protections have done
468
+ their work. The helper is not changing the policy goal; it is only forcing
469
+ the final integer allocation back inside the available slot budget.
470
+
471
+ Parameters:
472
+ - `internal` - - NEAT controller instance.
473
+ - `allocation` - - Allocation array to adjust.
474
+ - `remainingSlots` - - Total slots available.
475
+ - `minOffspringDefault` - - Default minimum offspring.
476
+
477
+ Returns: Nothing.
@@ -36,20 +36,66 @@ flowchart TD
36
36
 
37
37
  ## neat/evolve/runtime/evolve.runtime.utils.ts
38
38
 
39
- ### resolveStartTime
39
+ ### buildFittestSnapshot
40
40
 
41
41
  ```ts
42
- resolveStartTime(): number
42
+ buildFittestSnapshot(
43
+ internal: NeatControllerForEvolution,
44
+ ): default
43
45
  ```
44
46
 
45
- Resolve the start time for an evolution step.
47
+ Build a cloned Network from the current best genome.
46
48
 
47
- Evolve needs one timing origin that works in both browser-like and Node-like
48
- environments. This helper centralizes that choice so later elapsed-time reads
49
- can stay simple and the main evolve loop does not have to repeat environment
50
- detection inline.
49
+ The returned value from `evolve()` is meant to describe the generation that
50
+ was just analyzed, not the mutable genome object that will continue through
51
+ later controller operations. This helper therefore clones the current leader
52
+ into a standalone {@link Network} snapshot and preserves its score so callers
53
+ can inspect, serialize, or replay the champion without depending on mutable
54
+ controller-owned references.
51
55
 
52
- Returns: A timestamp in milliseconds or high-resolution timer units.
56
+ Parameters:
57
+ - `internal` - - NEAT controller instance.
58
+
59
+ Returns: A detached best-network snapshot for the current generation.
60
+
61
+ ### clearPopulationScores
62
+
63
+ ```ts
64
+ clearPopulationScores(
65
+ internal: NeatControllerForEvolution,
66
+ ): void
67
+ ```
68
+
69
+ Clear genome scores to force re-evaluation.
70
+
71
+ Once evolve has finished rebuilding and mutating the next population, the old
72
+ scores are no longer trustworthy. This helper makes that contract explicit by
73
+ clearing per-genome scores so the next call into the evolve or evaluate path
74
+ cannot accidentally treat structurally changed genomes as already evaluated.
75
+
76
+ Parameters:
77
+ - `internal` - - NEAT controller instance.
78
+
79
+ Returns: Nothing.
80
+
81
+ ### computeElapsedTime
82
+
83
+ ```ts
84
+ computeElapsedTime(
85
+ startTimestamp: number,
86
+ ): number
87
+ ```
88
+
89
+ Compute elapsed time since the start of evolve().
90
+
91
+ Runtime reporting belongs here because evolve uses the result as generation
92
+ bookkeeping rather than as a telemetry export concern. The helper mirrors the
93
+ start-time environment fallback so timing stays comparable across runtimes.
94
+
95
+ Parameters:
96
+ - `startTimestamp` - - Start time resolved earlier.
97
+
98
+ Returns: The elapsed runtime for the generation step.
53
99
 
54
100
  ### ensurePopulationEvaluated
55
101
 
@@ -72,26 +118,30 @@ Parameters:
72
118
 
73
119
  Returns: A promise that resolves once evaluation is guaranteed.
74
120
 
75
- ### updateGlobalBestTracking
121
+ ### resolveHighResolutionNow
76
122
 
77
123
  ```ts
78
- updateGlobalBestTracking(
79
- internal: NeatControllerForEvolution,
80
- ): void
124
+ resolveHighResolutionNow(): (() => number) | undefined
81
125
  ```
82
126
 
83
- Update generation-level best score tracking.
127
+ Resolve a high-resolution timer callback when the runtime exposes one.
84
128
 
85
- This helper maintains the controller's lightweight "best score seen in the
86
- current generation window" markers. Those markers are intentionally separate
87
- from the cloned best-network snapshot so the evolve loop can cheaply decide
88
- whether a fresh improvement occurred without conflating score bookkeeping with
89
- network serialization.
129
+ Returns: Timer callback or `undefined` when only wall-clock time is available.
90
130
 
91
- Parameters:
92
- - `internal` - - NEAT controller instance.
131
+ ### resolveStartTime
93
132
 
94
- Returns: Nothing.
133
+ ```ts
134
+ resolveStartTime(): number
135
+ ```
136
+
137
+ Resolve the start time for an evolution step.
138
+
139
+ Evolve needs one timing origin that works in both browser-like and Node-like
140
+ environments. This helper centralizes that choice so later elapsed-time reads
141
+ can stay simple and the main evolve loop does not have to repeat environment
142
+ detection inline.
143
+
144
+ Returns: A timestamp in milliseconds or high-resolution timer units.
95
145
 
96
146
  ### trackGlobalImprovement
97
147
 
@@ -116,73 +166,23 @@ Parameters:
116
166
 
117
167
  Returns: Nothing.
118
168
 
119
- ### computeElapsedTime
120
-
121
- ```ts
122
- computeElapsedTime(
123
- startTimestamp: number,
124
- ): number
125
- ```
126
-
127
- Compute elapsed time since the start of evolve().
128
-
129
- Runtime reporting belongs here because evolve uses the result as generation
130
- bookkeeping rather than as a telemetry export concern. The helper mirrors the
131
- start-time environment fallback so timing stays comparable across runtimes.
132
-
133
- Parameters:
134
- - `startTimestamp` - - Start time resolved earlier.
135
-
136
- Returns: The elapsed runtime for the generation step.
137
-
138
- ### clearPopulationScores
169
+ ### updateGlobalBestTracking
139
170
 
140
171
  ```ts
141
- clearPopulationScores(
172
+ updateGlobalBestTracking(
142
173
  internal: NeatControllerForEvolution,
143
174
  ): void
144
175
  ```
145
176
 
146
- Clear genome scores to force re-evaluation.
177
+ Update generation-level best score tracking.
147
178
 
148
- Once evolve has finished rebuilding and mutating the next population, the old
149
- scores are no longer trustworthy. This helper makes that contract explicit by
150
- clearing per-genome scores so the next call into the evolve or evaluate path
151
- cannot accidentally treat structurally changed genomes as already evaluated.
179
+ This helper maintains the controller's lightweight "best score seen in the
180
+ current generation window" markers. Those markers are intentionally separate
181
+ from the cloned best-network snapshot so the evolve loop can cheaply decide
182
+ whether a fresh improvement occurred without conflating score bookkeeping with
183
+ network serialization.
152
184
 
153
185
  Parameters:
154
186
  - `internal` - - NEAT controller instance.
155
187
 
156
188
  Returns: Nothing.
157
-
158
- ### buildFittestSnapshot
159
-
160
- ```ts
161
- buildFittestSnapshot(
162
- internal: NeatControllerForEvolution,
163
- ): default
164
- ```
165
-
166
- Build a cloned Network from the current best genome.
167
-
168
- The returned value from `evolve()` is meant to describe the generation that
169
- was just analyzed, not the mutable genome object that will continue through
170
- later controller operations. This helper therefore clones the current leader
171
- into a standalone {@link Network} snapshot and preserves its score so callers
172
- can inspect, serialize, or replay the champion without depending on mutable
173
- controller-owned references.
174
-
175
- Parameters:
176
- - `internal` - - NEAT controller instance.
177
-
178
- Returns: A detached best-network snapshot for the current generation.
179
-
180
- ### resolveHighResolutionNow
181
-
182
- ```ts
183
- resolveHighResolutionNow(): (() => number) | undefined
184
- ```
185
-
186
- Resolve a high-resolution timer callback when the runtime exposes one.
187
-
188
- Returns: Timer callback or `undefined` when only wall-clock time is available.