@reicek/neataptic-ts 0.1.26 → 0.1.27

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 (123) hide show
  1. package/.github/agents/boundary-mapper.agent.md +13 -8
  2. package/.github/agents/docs-scout.agent.md +14 -9
  3. package/.github/agents/plan-scout.agent.md +11 -6
  4. package/.github/agents/solid-split.agent.md +33 -17
  5. package/.github/copilot-instructions.md +100 -88
  6. package/.github/skills/educational-docs/SKILL.md +90 -40
  7. package/.github/skills/educational-docs/assets/mermaid-diagram-playbook.md +141 -141
  8. package/.github/skills/educational-docs/assets/visual-style-guide.md +1 -1
  9. package/.github/skills/plan-alignment/SKILL.md +1 -1
  10. package/.github/skills/solid-split/SKILL.md +54 -35
  11. package/.github/skills/solid-split/assets/docs-checklist.md +1 -1
  12. package/.github/skills/solid-split/assets/split-plan-template.md +41 -12
  13. package/.github/skills/solid-split/assets/split-workflow-checklist.md +4 -1
  14. package/.github/skills/test-fix-workflow/SKILL.md +12 -7
  15. package/.github/skills/trace-analyzer-extension/SKILL.md +1 -1
  16. package/.github/skills/trace-analyzer-extension/assets/extension-checklist.md +1 -1
  17. package/.github/skills/trace-analyzer-extension/references/analyzer-extension-workflow.md +1 -1
  18. package/.github/skills/trace-audit-reporting/SKILL.md +1 -1
  19. package/.github/skills/trace-audit-reporting/assets/performance-report-template.md +1 -1
  20. package/.github/skills/trace-audit-reporting/references/trace-analysis-workflow.md +1 -1
  21. package/.github/skills/tracker-handoff/SKILL.md +53 -5
  22. package/package.json +1 -1
  23. package/plans/Flappy_Bird_Folder_Documentation_Pass.logs.md +42 -0
  24. package/plans/Flappy_Bird_Folder_Documentation_Pass.md +22 -104
  25. package/plans/README.md +6 -2
  26. package/plans/Roadmap.md +35 -31
  27. package/plans/analyze-trace-solid-split.logs.md +35 -0
  28. package/plans/analyze-trace-solid-split.plans.md +21 -52
  29. package/plans/architecture-solid-split.logs.md +44 -0
  30. package/plans/architecture-solid-split.plans.md +20 -653
  31. package/plans/asciiMaze-typescript-repair.logs.md +35 -0
  32. package/plans/asciiMaze-typescript-repair.plans.md +30 -36
  33. package/plans/generate-docs-solid-split.logs.md +36 -0
  34. package/plans/generate-docs-solid-split.plans.md +21 -73
  35. package/plans/methods-docs.logs.md +37 -0
  36. package/plans/methods-docs.plans.md +22 -183
  37. package/plans/methods-solid-split.logs.md +41 -0
  38. package/plans/methods-solid-split.plans.md +23 -65
  39. package/plans/neat-docs.logs.md +38 -0
  40. package/plans/neat-docs.plans.md +21 -63
  41. package/plans/neat-test-surface-repair.logs.md +38 -0
  42. package/plans/neat-test-surface-repair.plans.md +24 -24
  43. package/plans/readme-first-section-pass.logs.md +63 -0
  44. package/plans/readme-first-section-pass.plans.md +42 -0
  45. package/plans/render-docs-html-solid-split.logs.md +36 -0
  46. package/plans/render-docs-html-solid-split.plans.md +20 -54
  47. package/plans/src-no-explicit-any-cleanup.logs.md +39 -0
  48. package/plans/src-no-explicit-any-cleanup.plans.md +23 -161
  49. package/plans/utils-docs.logs.md +37 -0
  50. package/plans/utils-docs.plans.md +20 -35
  51. package/src/README.md +88 -22
  52. package/src/architecture/README.md +94 -17
  53. package/src/architecture/activationArrayPool/README.md +53 -0
  54. package/src/architecture/activationArrayPool/activationArrayPool.ts +53 -0
  55. package/src/architecture/layer/README.md +94 -5
  56. package/src/architecture/layer/layer.ts +94 -5
  57. package/src/architecture/network/README.md +85 -14
  58. package/src/architecture/network/activate/README.md +301 -213
  59. package/src/architecture/network/activate/docs.order.json +9 -0
  60. package/src/architecture/network/activate/network.activate.utils.ts +90 -0
  61. package/src/architecture/network/connect/README.md +80 -3
  62. package/src/architecture/network/connect/docs.order.json +9 -0
  63. package/src/architecture/network/connect/network.connect.utils.ts +79 -0
  64. package/src/architecture/network/deterministic/README.md +96 -12
  65. package/src/architecture/network/deterministic/docs.order.json +10 -0
  66. package/src/architecture/network/deterministic/network.deterministic.utils.ts +90 -0
  67. package/src/architecture/network/evolve/README.md +286 -228
  68. package/src/architecture/network/evolve/docs.order.json +11 -0
  69. package/src/architecture/network/evolve/network.evolve.utils.ts +59 -0
  70. package/src/architecture/network/gating/README.md +58 -16
  71. package/src/architecture/network/gating/docs.order.json +9 -0
  72. package/src/architecture/network/gating/network.gating.utils.ts +43 -0
  73. package/src/architecture/network/genetic/README.md +75 -36
  74. package/src/architecture/network/genetic/docs.order.json +10 -0
  75. package/src/architecture/network/genetic/network.genetic.utils.ts +53 -17
  76. package/src/architecture/network/network.ts +91 -46
  77. package/src/architecture/network/standalone/README.md +309 -285
  78. package/src/architecture/network/standalone/docs.order.json +13 -0
  79. package/src/architecture/network/standalone/network.standalone.utils.ts +51 -28
  80. package/src/architecture/network.ts +94 -17
  81. package/src/architecture/nodePool/README.md +53 -0
  82. package/src/architecture/nodePool/nodePool.ts +53 -0
  83. package/src/methods/README.md +80 -34
  84. package/src/methods/methods.ts +80 -34
  85. package/src/methods/mutation/README.md +39 -93
  86. package/src/methods/mutation/mutation.ts +58 -0
  87. package/src/multithreading/README.md +114 -14
  88. package/src/multithreading/docs.order.json +5 -0
  89. package/src/multithreading/multi.ts +103 -7
  90. package/src/multithreading/types.ts +6 -1
  91. package/src/multithreading/workers/README.md +72 -2
  92. package/src/multithreading/workers/browser/README.md +39 -0
  93. package/src/multithreading/workers/browser/testworker.ts +40 -0
  94. package/src/multithreading/workers/node/README.md +50 -11
  95. package/src/multithreading/workers/node/docs.order.json +4 -0
  96. package/src/multithreading/workers/node/testworker.ts +43 -3
  97. package/src/multithreading/workers/workers.ts +36 -1
  98. package/src/neat/README.md +230 -152
  99. package/src/neat/adaptive/core/README.md +99 -42
  100. package/src/neat/adaptive/core/adaptive.core.ts +71 -14
  101. package/src/neat/adaptive/core/docs.order.json +8 -0
  102. package/src/neat/docs.order.json +9 -0
  103. package/src/neat/lineage/README.md +118 -16
  104. package/src/neat/lineage/lineage.ts +115 -13
  105. package/src/neat/neat.defaults.constants.ts +91 -13
  106. package/src/neat.ts +86 -20
  107. package/src/utils/README.md +71 -21
  108. package/src/utils/memory.ts +69 -19
  109. package/test/examples/asciiMaze/browser-entry/README.md +81 -8
  110. package/test/examples/asciiMaze/browser-entry/browser-entry.ts +81 -8
  111. package/test/examples/asciiMaze/dashboardManager/README.md +68 -4
  112. package/test/examples/asciiMaze/dashboardManager/dashboardManager.ts +68 -4
  113. package/test/examples/asciiMaze/evolutionEngine/README.md +1259 -1174
  114. package/test/examples/asciiMaze/evolutionEngine/docs.order.json +10 -0
  115. package/test/examples/asciiMaze/evolutionEngine/evolutionEngine.types.ts +87 -0
  116. package/test/examples/asciiMaze/mazeMovement/README.md +81 -4
  117. package/test/examples/asciiMaze/mazeMovement/mazeMovement.ts +81 -4
  118. package/test/examples/flappy_bird/browser-entry/README.md +64 -21
  119. package/test/examples/flappy_bird/browser-entry/browser-entry.ts +64 -21
  120. package/test/examples/flappy_bird/flappy-evolution-worker/README.md +98 -10
  121. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.ts +98 -10
  122. package/test/examples/flappy_bird/simulation-shared/README.md +88 -4
  123. package/test/examples/flappy_bird/simulation-shared/simulation-shared.types.ts +88 -4
@@ -1,23 +1,101 @@
1
1
  import type { NeatConstructorDefaults } from './init/neat.init';
2
2
 
3
3
  /**
4
- * Public default knobs for the root `Neat` controller.
4
+ * Root chapter map and public default knobs for the internal `src/neat` controller surface.
5
5
  *
6
- * These constants describe the controller personality a caller gets before a
7
- * custom option bag starts bending the run toward a different search style.
8
- * Keeping them in their own root chapter lets `src/neat.ts` stay focused on
9
- * orchestration while the `init/` chapter consumes one shared defaults packet.
6
+ * `src/neat.ts` is the public control desk. `src/neat/` is the machine room
7
+ * behind it. This folder owns the controller chapters that make a run real:
8
+ * initialization, evaluation, evolution, mutation, speciation, telemetry,
9
+ * persistence, and the shared bookkeeping that keeps experiments deterministic
10
+ * instead of magical. Promoting the defaults file to the chapter opening is
11
+ * intentional because default knobs are the quickest way to make the
12
+ * controller's personality legible before a reader dives into implementation
13
+ * detail.
10
14
  *
11
- * The constants fall into four small families:
15
+ * The most helpful reading move is to split the folder into four working
16
+ * lanes. `init/`, `evaluate/`, and `evolve/` explain how a population is
17
+ * created, scored, and replaced. `mutation/`, `selection/`, and `speciation/`
18
+ * explain how search pressure and diversity are managed. `telemetry/`,
19
+ * `lineage/`, `diversity/`, and `multiobjective/` explain how the run becomes
20
+ * inspectable. `export/`, `rng/`, `cache/`, `maintenance/`, and `pruning/`
21
+ * explain how the controller stays reproducible and tractable as experiments
22
+ * get larger.
12
23
  *
13
- * - search volume and tempo,
14
- * - speciation pressure,
15
- * - structural ceilings,
16
- * - observability sampling.
24
+ * The flat root files are small bridges rather than the whole story.
25
+ * `neat.defaults.constants.ts` and `neat.types.ts` keep the public constructor
26
+ * and option bag readable. `neat.lineage.ts` and `neat.constants.ts` keep
27
+ * small shared logic close to the root when multiple chapters need it. The
28
+ * deeper folders own the heavier policy and runtime details.
17
29
  *
18
- * Read them as the public defaults shelf, not as hidden implementation trivia.
19
- * These values are the baseline promises the root controller makes when a user
20
- * says, "give me an ordinary NEAT run," without specifying every knob.
30
+ * These defaults matter because they are the baseline promises the controller
31
+ * makes when a caller says "give me an ordinary NEAT run." Population size,
32
+ * mutation tempo, compatibility pressure, structural ceilings, and
33
+ * observability sampling are not random numbers. They are the quiet assumptions
34
+ * that decide whether the controller behaves like a conservative search, an
35
+ * exploratory search, or an unstable one.
36
+ *
37
+ * That design follows the original NEAT intuition: protect structural
38
+ * innovation long enough for it to compete, rather than forcing every new
39
+ * topology to beat established species immediately. See Stanley and
40
+ * Miikkulainen,
41
+ * [Evolving Neural Networks through Augmenting Topologies](https://nn.cs.utexas.edu/?stanley:ec02),
42
+ * for the background behind the compatibility and growth vocabulary that keeps
43
+ * surfacing across this folder.
44
+ *
45
+ * Read this root chapter in three passes. Start with this defaults file and
46
+ * `neat.types.ts` for the public knobs and broad contracts. Continue into
47
+ * `evaluate/`, `evolve/`, and `speciation/` for the live search loop. Finish
48
+ * with `telemetry/`, `lineage/`, `multiobjective/`, `export/`, and `rng/` when
49
+ * you want to inspect, replay, or compare runs rather than only advance them.
50
+ *
51
+ * ```mermaid
52
+ * flowchart TD
53
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
54
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
55
+ *
56
+ * Root["src/neat root"]:::accent --> Loop["init / evaluate / evolve"]:::base
57
+ * Root --> Pressure["mutation / selection / speciation"]:::base
58
+ * Root --> Observe["telemetry / lineage / diversity / multiobjective"]:::base
59
+ * Root --> Replay["export / rng / cache / maintenance / pruning"]:::base
60
+ * Root --> Bridges["root bridges<br/>defaults / types / constants"]:::base
61
+ * ```
62
+ *
63
+ * ```mermaid
64
+ * flowchart LR
65
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
66
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
67
+ *
68
+ * Defaults[Root defaults]:::accent --> Population[popsize elitism provenance]:::base
69
+ * Defaults --> Variation[mutationRate mutationAmount]:::base
70
+ * Defaults --> Species[compatibility and weight coefficients]:::base
71
+ * Defaults --> Observation[diversity and novelty samples]:::base
72
+ * Population --> Run[Controller behavior]:::base
73
+ * Variation --> Run
74
+ * Species --> Run
75
+ * Observation --> Run
76
+ * ```
77
+ *
78
+ * Example: build one explicit baseline options bag from the documented root
79
+ * defaults.
80
+ *
81
+ * ```ts
82
+ * const baselineOptions = {
83
+ * popsize: DEFAULT_POPULATION_SIZE,
84
+ * mutationRate: DEFAULT_MUTATION_RATE,
85
+ * compatibilityThreshold: DEFAULT_COMPATIBILITY_THRESHOLD,
86
+ * };
87
+ * ```
88
+ *
89
+ * Example: keep the observability defaults visible when teaching or
90
+ * benchmarking runs.
91
+ *
92
+ * ```ts
93
+ * const observabilityDefaults = {
94
+ * diversityPairSample: DEFAULT_DIVERSITY_PAIR_SAMPLE,
95
+ * diversityGraphletSample: DEFAULT_DIVERSITY_GRAPHLET_SAMPLE,
96
+ * noveltyK: DEFAULT_NOVELTY_K,
97
+ * };
98
+ * ```
21
99
  */
22
100
 
23
101
  /**
package/src/neat.ts CHANGED
@@ -90,34 +90,100 @@ import * as neatTelemetryFacade from './neat/telemetry/facade/telemetry.facade';
90
90
  /**
91
91
  * Root orchestration surface for NeuroEvolution of Augmenting Topologies (NEAT) in NeatapticTS.
92
92
  *
93
- * Within the broader `src` surface, this file is the public chapter map for the
94
- * library's evolutionary controller.
95
- * The heavy algorithmic work lives in focused `src/neat/**` modules, but this
96
- * root surface keeps the user-facing workflow readable: configure a population,
97
- * evaluate genomes, evolve the next generation, inspect telemetry, and persist
98
- * the state when a run becomes worth keeping.
93
+ * This root chapter is the public control desk for the library. The
94
+ * architecture surfaces explain what a network graph is. The `src/neat/**`
95
+ * chapters explain how evaluation, reproduction, speciation, telemetry, and
96
+ * persistence work in detail. This file sits between those two layers and
97
+ * answers the first practical reader question: how do I run one evolutionary
98
+ * experiment without learning every subsystem in the same breath?
99
99
  *
100
- * What this file covers:
101
- * - the high-level lifecycle of a NEAT run,
102
- * - the default knobs that shape population growth and speciation,
103
- * - reproducibility helpers such as seeded RNG snapshots and state export,
104
- * - educational inspection hooks for telemetry, species history, diversity, and Pareto fronts.
100
+ * That boundary matters because a useful NEAT run is more than "mutate a
101
+ * network." A controller has to keep a population alive, protect enough
102
+ * diversity to avoid early collapse, score genomes fairly, record what
103
+ * happened, and give the caller a deterministic way to pause or resume the
104
+ * search. The root surface is where those responsibilities become one readable
105
+ * workflow instead of a pile of helper calls.
105
106
  *
106
- * What you can learn here:
107
- * - how the top-level controller stays orchestration-first even after the internal SOLID split,
108
- * - which public methods belong to setup, evolution, diagnostics, and persistence,
109
- * - which subsystem README to open next when you want the underlying mechanics.
107
+ * One helpful mental model is to read the controller as four shelves. The setup
108
+ * shelf decides population size, defaults, and reproducibility. The search
109
+ * shelf drives `evaluate()`, `evolve()`, and the public mutation hooks. The
110
+ * observability shelf exposes telemetry, lineage, diversity, species, and
111
+ * Pareto views. The persistence shelf turns a live run into replayable state
112
+ * through `toJSON()`, `exportState()`, and RNG snapshots.
113
+ *
114
+ * The chapter also exists to keep the public class orchestration-first after
115
+ * the internal split. `src/neat/**` now owns the heavier policy chapters:
116
+ * `evaluate/` scores genomes, `evolve/` creates the next generation,
117
+ * `speciation/` manages compatibility pressure, `telemetry/` records what the
118
+ * run did, and `export/` plus `rng/` keep experiments reproducible. If you can
119
+ * read the root workflow first, the subchapters become "why does this step
120
+ * work?" reads instead of "where do I even start?" reads.
121
+ *
122
+ * The guiding historical idea comes from Stanley and Miikkulainen's NEAT
123
+ * paper: evolve both weights and topology while protecting innovation long
124
+ * enough for new structures to prove useful. See Stanley and Miikkulainen,
125
+ * [Evolving Neural Networks through Augmenting Topologies](https://nn.cs.utexas.edu/?stanley:ec02),
126
+ * for the compact background behind the controller vocabulary that appears all
127
+ * through this surface.
128
+ *
129
+ * Read this root when you want to answer one of three questions quickly: how to
130
+ * start a run, how to move it forward generation by generation, or how to
131
+ * inspect and persist it without diving into every implementation chapter. Read
132
+ * the narrower `src/neat/**` READMEs when the next question becomes about one
133
+ * specific policy family rather than the whole experiment loop.
110
134
  *
111
135
  * ```mermaid
112
136
  * flowchart LR
113
- * Configure["Configure run<br/>sizes + fitness + options"] --> Seed["Seed or restore<br/>constructor / createPool / import"]
114
- * Seed --> Score["Score population<br/>evaluate()"]
115
- * Score --> Breed["Breed next generation<br/>evolve() / mutate()"]
116
- * Breed --> Observe["Observe search pressure<br/>telemetry / species / diversity / Pareto"]
117
- * Observe --> Persist["Persist or replay<br/>exportState() / toJSON() / RNG state"]
137
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
138
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
139
+ *
140
+ * Configure["Configure run<br/>sizes + fitness + options"]:::accent --> Seed["Seed or restore<br/>constructor / createPool / import"]:::base
141
+ * Seed --> Score["Score population<br/>evaluate()"]:::base
142
+ * Score --> Breed["Breed next generation<br/>evolve() / mutate()"]:::accent
143
+ * Breed --> Observe["Observe pressure<br/>telemetry / species / diversity / Pareto"]:::base
144
+ * Observe --> Persist["Persist or replay<br/>exportState() / toJSON() / RNG state"]:::base
118
145
  * Breed --> Score
119
146
  * ```
120
147
  *
148
+ * ```mermaid
149
+ * flowchart TD
150
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
151
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
152
+ *
153
+ * Root["src root controller"]:::accent --> Setup["Defaults and initialization<br/>constructor / createPool / import"]:::base
154
+ * Root --> Search["Search loop<br/>evaluate / evolve / mutate"]:::base
155
+ * Root --> Observe["Diagnostics<br/>telemetry / species / lineage / Pareto"]:::base
156
+ * Root --> Replay["Persistence<br/>toJSON / exportState / RNG"]:::base
157
+ * Search --> Chapters["Detailed policy chapters<br/>src/neat/**"]:::base
158
+ * ```
159
+ *
160
+ * Example: start a small deterministic run and inspect the best score after one
161
+ * generation.
162
+ *
163
+ * ```ts
164
+ * const neat = new Neat(2, 1, fitness, {
165
+ * popsize: 50,
166
+ * seed: 7,
167
+ * fastMode: true,
168
+ * });
169
+ *
170
+ * await neat.evaluate();
171
+ * const bestGenome = await neat.evolve();
172
+ *
173
+ * console.log(bestGenome.score);
174
+ * ```
175
+ *
176
+ * Example: capture telemetry and a replayable snapshot after the current run
177
+ * step.
178
+ *
179
+ * ```ts
180
+ * const latestTelemetry = neat.getTelemetry().at(-1);
181
+ * const exportedState = neat.exportState();
182
+ *
183
+ * console.log(latestTelemetry?.generation);
184
+ * console.log(exportedState.neat.generation);
185
+ * ```
186
+ *
121
187
  * Recommended reading after this root chapter:
122
188
  * - `./neat/evaluate/README.md` for scoring flow and objective handling
123
189
  * - `./neat/evolve/README.md` for reproduction orchestration
@@ -1,23 +1,44 @@
1
1
  # utils
2
2
 
3
- Memory instrumentation utilities (Phase 0).
3
+ Memory instrumentation chapter for slab, pool, and heap comparisons.
4
4
 
5
5
  This chapter exists for one practical learning problem: memory behavior is
6
6
  one of the easiest parts of an evolutionary system to feel, but one of the
7
7
  hardest parts to explain from raw runtime objects alone. Networks grow,
8
8
  slabs reserve capacity ahead of immediate need, pools trade fresh allocation
9
9
  pressure for reuse, and the JavaScript engine adds object overhead that is
10
- hard to see directly from the outside.
10
+ difficult to see directly from the outside.
11
11
 
12
12
  Instead of pretending to be a precise profiler, this boundary offers a fast,
13
13
  educational snapshot. The goal is to make design choices visible enough that
14
- readers can compare runs and ask better questions:
15
-
16
- - Did moving toward slab-backed storage reduce object-heavy overhead?
17
- - Is pooling shifting pressure away from fresh allocations?
18
- - How much reserved typed-array capacity is currently going unused?
19
- - Are browser or Node heap readings moving in the same direction as the
20
- heuristic network summary?
14
+ readers can compare runs and ask better questions: did slab-backed storage
15
+ reduce object-heavy overhead, is pooling shifting pressure away from fresh
16
+ allocations, how much reserved typed-array capacity is currently unused, and
17
+ are browser or Node heap readings moving in the same direction as the
18
+ library-specific heuristics?
19
+
20
+ The most important design choice is scope. `memoryStats()` is not trying to
21
+ replace a full heap profiler. It is trying to put library-shaped numbers next
22
+ to runtime-shaped numbers so a reader can compare architecture decisions with
23
+ less guesswork. The result is intentionally strongest at trend questions such
24
+ as "did the slab version get leaner?" or "did pooling reduce fresh pressure?"
25
+ rather than forensic questions about one exact byte count.
26
+
27
+ A useful mental model is to treat the snapshot as four cooperating layers.
28
+ The network layer counts connections, nodes, and estimated totals. The slab
29
+ layer explains reserved versus used typed-array capacity. The pool layer
30
+ exposes reuse infrastructure. The environment layer shows the coarser browser
31
+ or Node counters surrounding the library's own heuristics.
32
+
33
+ The environment metrics are intentionally coarser than the network heuristics.
34
+ See MDN,
35
+ [Performance.memory](https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory),
36
+ and the Node.js docs,
37
+ [process.memoryUsage()](https://nodejs.org/api/process.html#processmemoryusage),
38
+ for the runtime-level counters this chapter folds alongside its own snapshot.
39
+ They are useful context, but they do not know the difference between live
40
+ network structure, reserved slab capacity, and reusable pools the way this
41
+ module does.
21
42
 
22
43
  Read the chapter in three passes:
23
44
 
@@ -26,20 +47,49 @@ Read the chapter in three passes:
26
47
  3. `memory.utils.ts` when you want the aggregation, environment probing, and
27
48
  slab-accounting mechanics behind the snapshot.
28
49
 
29
- Design principles:
30
-
31
- - Lightweight: avoid deep graph walks or JSON serialization.
32
- - Pay-for-use: if no networks are registered the snapshot stays small.
33
- - Cross-environment: gather what the browser or Node can expose safely.
34
- - Extensible: keep room for later phases that add more exact accounting.
35
-
36
50
  ```mermaid
37
51
  flowchart TD
38
- Networks[Tracked or explicit networks] --> Aggregation[Heuristic network aggregation]
39
- Aggregation --> Snapshot[MemoryStats snapshot]
40
- Config[Config and allocator flags] --> Snapshot
41
- Environment[Browser or Node heap probes] --> Snapshot
42
- Snapshot --> Questions[Compare storage strategy, pooling, and capacity behavior]
52
+ classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
53
+ classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
54
+
55
+ Networks[Tracked or explicit networks]:::base --> Aggregation[Heuristic network aggregation]:::accent
56
+ Aggregation --> Snapshot[MemoryStats snapshot]:::base
57
+ Config[Config and allocator flags]:::base --> Snapshot
58
+ Environment[Browser or Node heap probes]:::base --> Snapshot
59
+ Snapshot --> Questions[Compare storage strategy, pooling, and capacity behavior]:::base
60
+ ```
61
+
62
+ ```mermaid
63
+ flowchart LR
64
+ classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
65
+ classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
66
+
67
+ Stats[MemoryStats]:::accent --> NetworkLayer[connections nodes estimatedTotalBytes]:::base
68
+ Stats --> SlabLayer[slabBytes reservedBytes usedBytes fragmentationPct]:::base
69
+ Stats --> PoolLayer[nodePool reuse snapshot]:::base
70
+ Stats --> EnvironmentLayer[browser heap or Node RSS counters]:::base
71
+ ```
72
+
73
+ Example: register one network once, then capture snapshots later without
74
+ threading the target through every call.
75
+
76
+ ```ts
77
+ registerTrackedNetwork(network);
78
+ const snapshot = memoryStats();
79
+
80
+ console.log(snapshot.estimatedTotalBytes);
81
+ console.log(snapshot.slabs.fragmentationPct);
82
+ ```
83
+
84
+ Example: compare two explicit network sets when you want the memory story to
85
+ stay local to one experiment.
86
+
87
+ ```ts
88
+ const baselineSnapshot = memoryStats([baselineNetwork]);
89
+ const pooledSnapshot = memoryStats([pooledNetwork]);
90
+
91
+ console.log(baselineSnapshot.estimatedTotalBytes);
92
+ console.log(pooledSnapshot.slabs.pooledFraction);
43
93
  ```
44
94
 
45
95
  ## utils/memory.ts
@@ -1,22 +1,43 @@
1
1
  /**
2
- * Memory instrumentation utilities (Phase 0).
2
+ * Memory instrumentation chapter for slab, pool, and heap comparisons.
3
3
  *
4
4
  * This chapter exists for one practical learning problem: memory behavior is
5
5
  * one of the easiest parts of an evolutionary system to feel, but one of the
6
6
  * hardest parts to explain from raw runtime objects alone. Networks grow,
7
7
  * slabs reserve capacity ahead of immediate need, pools trade fresh allocation
8
8
  * pressure for reuse, and the JavaScript engine adds object overhead that is
9
- * hard to see directly from the outside.
9
+ * difficult to see directly from the outside.
10
10
  *
11
11
  * Instead of pretending to be a precise profiler, this boundary offers a fast,
12
12
  * educational snapshot. The goal is to make design choices visible enough that
13
- * readers can compare runs and ask better questions:
13
+ * readers can compare runs and ask better questions: did slab-backed storage
14
+ * reduce object-heavy overhead, is pooling shifting pressure away from fresh
15
+ * allocations, how much reserved typed-array capacity is currently unused, and
16
+ * are browser or Node heap readings moving in the same direction as the
17
+ * library-specific heuristics?
14
18
  *
15
- * - Did moving toward slab-backed storage reduce object-heavy overhead?
16
- * - Is pooling shifting pressure away from fresh allocations?
17
- * - How much reserved typed-array capacity is currently going unused?
18
- * - Are browser or Node heap readings moving in the same direction as the
19
- * heuristic network summary?
19
+ * The most important design choice is scope. `memoryStats()` is not trying to
20
+ * replace a full heap profiler. It is trying to put library-shaped numbers next
21
+ * to runtime-shaped numbers so a reader can compare architecture decisions with
22
+ * less guesswork. The result is intentionally strongest at trend questions such
23
+ * as "did the slab version get leaner?" or "did pooling reduce fresh pressure?"
24
+ * rather than forensic questions about one exact byte count.
25
+ *
26
+ * A useful mental model is to treat the snapshot as four cooperating layers.
27
+ * The network layer counts connections, nodes, and estimated totals. The slab
28
+ * layer explains reserved versus used typed-array capacity. The pool layer
29
+ * exposes reuse infrastructure. The environment layer shows the coarser browser
30
+ * or Node counters surrounding the library's own heuristics.
31
+ *
32
+ * The environment metrics are intentionally coarser than the network heuristics.
33
+ * See MDN,
34
+ * [Performance.memory](https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory),
35
+ * and the Node.js docs,
36
+ * [process.memoryUsage()](https://nodejs.org/api/process.html#processmemoryusage),
37
+ * for the runtime-level counters this chapter folds alongside its own snapshot.
38
+ * They are useful context, but they do not know the difference between live
39
+ * network structure, reserved slab capacity, and reusable pools the way this
40
+ * module does.
20
41
  *
21
42
  * Read the chapter in three passes:
22
43
  *
@@ -25,20 +46,49 @@
25
46
  * 3. `memory.utils.ts` when you want the aggregation, environment probing, and
26
47
  * slab-accounting mechanics behind the snapshot.
27
48
  *
28
- * Design principles:
49
+ * ```mermaid
50
+ * flowchart TD
51
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
52
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
29
53
  *
30
- * - Lightweight: avoid deep graph walks or JSON serialization.
31
- * - Pay-for-use: if no networks are registered the snapshot stays small.
32
- * - Cross-environment: gather what the browser or Node can expose safely.
33
- * - Extensible: keep room for later phases that add more exact accounting.
54
+ * Networks[Tracked or explicit networks]:::base --> Aggregation[Heuristic network aggregation]:::accent
55
+ * Aggregation --> Snapshot[MemoryStats snapshot]:::base
56
+ * Config[Config and allocator flags]:::base --> Snapshot
57
+ * Environment[Browser or Node heap probes]:::base --> Snapshot
58
+ * Snapshot --> Questions[Compare storage strategy, pooling, and capacity behavior]:::base
59
+ * ```
34
60
  *
35
61
  * ```mermaid
36
- * flowchart TD
37
- * Networks[Tracked or explicit networks] --> Aggregation[Heuristic network aggregation]
38
- * Aggregation --> Snapshot[MemoryStats snapshot]
39
- * Config[Config and allocator flags] --> Snapshot
40
- * Environment[Browser or Node heap probes] --> Snapshot
41
- * Snapshot --> Questions[Compare storage strategy, pooling, and capacity behavior]
62
+ * flowchart LR
63
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
64
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
65
+ *
66
+ * Stats[MemoryStats]:::accent --> NetworkLayer[connections nodes estimatedTotalBytes]:::base
67
+ * Stats --> SlabLayer[slabBytes reservedBytes usedBytes fragmentationPct]:::base
68
+ * Stats --> PoolLayer[nodePool reuse snapshot]:::base
69
+ * Stats --> EnvironmentLayer[browser heap or Node RSS counters]:::base
70
+ * ```
71
+ *
72
+ * Example: register one network once, then capture snapshots later without
73
+ * threading the target through every call.
74
+ *
75
+ * ```ts
76
+ * registerTrackedNetwork(network);
77
+ * const snapshot = memoryStats();
78
+ *
79
+ * console.log(snapshot.estimatedTotalBytes);
80
+ * console.log(snapshot.slabs.fragmentationPct);
81
+ * ```
82
+ *
83
+ * Example: compare two explicit network sets when you want the memory story to
84
+ * stay local to one experiment.
85
+ *
86
+ * ```ts
87
+ * const baselineSnapshot = memoryStats([baselineNetwork]);
88
+ * const pooledSnapshot = memoryStats([pooledNetwork]);
89
+ *
90
+ * console.log(baselineSnapshot.estimatedTotalBytes);
91
+ * console.log(pooledSnapshot.slabs.pooledFraction);
42
92
  * ```
43
93
  */
44
94
  import { config } from '../config';
@@ -1,15 +1,88 @@
1
1
  # browser-entry
2
2
 
3
- Public browser entry facade for the ASCII Maze demo module boundary.
3
+ Browser-hosted curriculum boundary for the ASCII Maze example.
4
+
5
+ This folder is where a long-running maze experiment becomes a browser
6
+ experience a human can actually steer and inspect. The evolution engine still
7
+ owns search, scoring, and curriculum advancement. The browser-entry boundary
8
+ owns host elements, resize behavior, telemetry fan-out, globals
9
+ compatibility, and the lifecycle handle that embedding code talks to.
10
+
11
+ Read it as a boundary between two clocks. One clock belongs to the maze
12
+ curriculum that carries refined winners into larger procedural mazes. The
13
+ other clock belongs to the browser host that has to paint dashboards, react
14
+ to cancellation, and stay polite to resize or unload events. `browser-entry/`
15
+ exists so those clocks can cooperate without collapsing into one monolithic
16
+ demo script.
17
+
18
+ That separation matters because `index.html` is intentionally thin. The page
19
+ only loads the published bundle from `docs/assets`, exposes a globals bridge,
20
+ and then hands off to this start surface. If you want the real host/runtime
21
+ seam, start here instead of with the HTML shell.
22
+
23
+ A second useful mental model is ownership. This folder does not own maze
24
+ fitness, winner refinement, or solve thresholds. Those stay in
25
+ `evolutionEngine/`. The host boundary owns container resolution, dashboard
26
+ plumbing, cooperative abort wiring, and the stable run handle that browser
27
+ callers can stop, await, or subscribe to.
28
+
29
+ Read the chapter in three passes. Start with `browser-entry.ts` for the
30
+ public `start(...)` surface. Continue to `browser-entry.services.ts` for host
31
+ assembly, globals wiring, and curriculum hand-off. Finish with the constants,
32
+ curriculum, and host helper files when you want the browser-specific
33
+ mechanics rather than the public lifecycle contract.
34
+
35
+ ```mermaid
36
+ flowchart LR
37
+ classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
38
+ classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
39
+
40
+ HtmlShell["index.html\nbundle loader"]:::base --> Globals["window globals\ncompatibility bridge"]:::base
41
+ Globals --> Start["start(...)\npublic browser entry"]:::accent
42
+ Start --> Host["host services\ndashboard + resize + container"]:::base
43
+ Start --> Curriculum["runBrowserEntryCurriculum\nphase orchestration"]:::base
44
+ Curriculum --> Engine["Evolution engine\nsearch and solve logic"]:::base
45
+ Host --> Handle["AsciiMazeRunHandle\nstop done telemetry"]:::base
46
+ Curriculum --> Handle
47
+ ```
48
+
49
+ ```mermaid
50
+ flowchart TD
51
+ classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
52
+ classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
53
+
54
+ BrowserEntry["browser-entry/"]:::accent --> PublicApi["browser-entry.ts\npublic start surface"]:::base
55
+ BrowserEntry --> Services["browser-entry.services.ts\nhost and globals assembly"]:::base
56
+ BrowserEntry --> Curriculum["browser-entry.curriculum.services.ts\nphase hand-off"]:::base
57
+ BrowserEntry --> HostUtils["browser-entry.host.services.ts\nand utils"]:::base
58
+ BrowserEntry --> Types["browser-entry.types.ts\nrun-handle contracts"]:::base
59
+ ```
60
+
61
+ For background reading on the cooperative stop side of the boundary, see
62
+ MDN, [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController),
63
+ which is the browser primitive this entry layer uses to compose internal and
64
+ caller-provided cancellation without moving DOM concerns into the engine.
65
+
66
+ Example: boot the browser demo from embedding code and stop it later.
67
+
68
+ ```ts
69
+ const handle = await start('ascii-maze-output');
70
+
71
+ setTimeout(() => handle.stop(), 5_000);
72
+ await handle.done;
73
+ ```
74
+
75
+ Example: subscribe to telemetry while the curriculum advances.
4
76
 
5
- The folder now owns host bootstrap, runtime orchestration, globals
6
- compatibility, and resize handling behind focused helpers. This facade keeps
7
- the public API stable while presenting a small orchestration-first surface.
77
+ ```ts
78
+ const handle = await start('ascii-maze-output');
79
+ const unsubscribe = handle.onTelemetry((telemetry) => {
80
+ console.log(telemetry.generation, telemetry.bestFitness);
81
+ });
8
82
 
9
- Educational note:
10
- `index.html` is only the browser shell that loads the prebuilt bundle and
11
- forwards into this API through window globals. If you want the real browser
12
- host boundary, start here rather than with the HTML loader.
83
+ await handle.done;
84
+ unsubscribe();
85
+ ```
13
86
 
14
87
  ## browser-entry/browser-entry.types.ts
15
88