Context
sample_hidden_graph(seed) in leadforge/structure/sampler.py currently constructs a fresh np.random.default_rng(seed) directly from the integer seed. The repo convention (established in leadforge/core/rng.py) is that all stochastic components derive their randomness from a single RNGRoot(seed) with named child streams.
Problem
Bypassing RNGRoot makes cross-component RNG coupling harder to control when the sampler is integrated with the simulation engine. It also means the seed space isn't partitioned the same way as other components.
Proposed fix
When the sampler is wired into Generator/the simulation pipeline (M5/M6), change the API to accept an RNGRoot or a named substream:
rng_root = RNGRoot(seed)
graph_rng = rng_root.child("hidden_graph")
g = sample_hidden_graph(rng=graph_rng, motif_family_name=...)
Why deferred
The right substream name and API shape depends on how Generator calls the sampler — which is defined in Milestone 5 (population generation). Designing the interface now would be premature.
Raised by Copilot in PR #8.
Context
sample_hidden_graph(seed)inleadforge/structure/sampler.pycurrently constructs a freshnp.random.default_rng(seed)directly from the integer seed. The repo convention (established inleadforge/core/rng.py) is that all stochastic components derive their randomness from a singleRNGRoot(seed)with named child streams.Problem
Bypassing
RNGRootmakes cross-component RNG coupling harder to control when the sampler is integrated with the simulation engine. It also means the seed space isn't partitioned the same way as other components.Proposed fix
When the sampler is wired into
Generator/the simulation pipeline (M5/M6), change the API to accept anRNGRootor a named substream:Why deferred
The right substream name and API shape depends on how
Generatorcalls the sampler — which is defined in Milestone 5 (population generation). Designing the interface now would be premature.Raised by Copilot in PR #8.