Skip to content

Release/v3.4.0#1

Merged
rkv0id merged 9 commits intomainfrom
release/v3.4.0
Apr 18, 2026
Merged

Release/v3.4.0#1
rkv0id merged 9 commits intomainfrom
release/v3.4.0

Conversation

@rkv0id
Copy link
Copy Markdown
Owner

@rkv0id rkv0id commented Apr 18, 2026

v3.4.0 — Signal field physics, quality metric overhaul, viewer improvements

This release completes the signal field introduced in v3.3.0 with corrected physics, a new multi-component quality metric, spatial signal visualization, and substantial viewer improvements across the archive and ecosystem pages.

Signal field physics corrections

  • emission_rate (scalar) and decay_rates (16-channel vector) are now per-creature searchable parameters replacing hardcoded platform constants
  • Standard preset bumped to 500 steps; signal preset auto-selects 800 steps with --signal-field
  • CREATURE_MASS_FLOOR raised to 0.2 to create selection pressure against mass bleed

Quality metric overhaul

  • New three-component score: q = w_c · min(compact(T/2), compact(T)) + w_s · stability + w_r · retention
  • Two-point compactness catches early-peak degraders that score well at the final step but were already diffuse at midpoint -- the key failure mode for long ecosystem runs
  • Continuous stability term replaces binary persistent filter as a quality component: clip(1 − drift/0.2, 0, 1)
  • Signal retention term for signal runs: clip(final_mass/initial_mass, 0, 1) weighted at 0.2
  • midpoint_state captured during rollout and stored on RolloutTrace

Signal observables

  • SimOutput captures signal_total_history, signal_channel_snapshots, species_signal_received, and signal_sum_snapshots (downsampled spatial signal for GIF generation)
  • EcosystemMeasures gains 6 new fields: signal total history, mass fraction, channel snapshots, dominant channel history, receptor alignment, emission-reception compatibility matrix
  • Signal GIF generated alongside ecosystem GIF using species-colored teal colormap; Mass/Signal tab toggle in ecosystem viewer

Viewer improvements

  • Archive view: SIGNAL badge on run header; signal params section in creature modal with per-channel bar charts for emission_vector, receptor_profile, decay_rates
  • Ecosystem view: SIGNAL badge in run header; outcome label tooltips; signal charts sidebar (total history, mass fraction, receptor alignment, emission-reception heatmap); mass chart label corrected; Mass/Signal GIF toggle replaces broken canvas overlay
  • Index: System tab restructured with internal anchor nav (Architecture · Search · Quality metric · Ecosystem · Signal field · Descriptors); quality metric section with formula; signal field section with diagram and step-by-step physics; SIGNAL badge on ecosystem run cards; outcome label shown on cards
  • Signal field mechanics SVG diagram added to docs and embedded in index

Infrastructure

  • pyright warning count reduced to 0 by suppressing third-party stub noise categories
  • smoke_ecosystem.sh verifies signal.gif presence for signal-active runs
  • 401 tests, 0 errors, 0 warnings

rkv0id added 2 commits April 18, 2026 14:09
Signal params (emission_rate, decay_rates) are now per-creature searchable
parameters rather than platform-level constants. Removed EMISSION_RATE=0.02
and _DECAY_RATES from flowlenia.py entirely.

params.py / result.py
- emission_rate: scalar [0.001, 0.05], sigma 0.005
- decay_rates: (C,) vector [0, 0.9], sigma 0.05
- Both added to SIGNAL_PARAMETER_SPECS, sample_random, mutate, in_range
- _SignalParams TypedDict extended with both fields

flowlenia.py / localized.py
- Params gains emission_rate: float | None and decay_rates: Tensor | None
- _decay built from params.decay_rates at construction time
- step() uses params.emission_rate (zero-safe fallback when None)
- localized.py uses per-species emission_rate for each species

rollout.py / run.py
- _params_dict_to_tensors and _params_from_creature convert both new params

quality.py
- CREATURE_MASS_FLOOR raised 0.1 -> 0.2 (stricter mass bleed selection)
- signal_retention term: quality = 0.7 * compactness + 0.3 * (final_mass/initial_mass)
  applied when final_signal_mass > 0 or initial_total > initial_mass

Presets / CLI
- standard_preset: 300 -> 500 steps
- signal_preset(): new, 192x192, 800 steps
- CLI auto-selects signal_preset when --signal-field and no --steps override

Tests
- test_rollout.py: updated standard preset assertion (300->500), added signal_preset test
- test_signal.py: new keys in all key-presence checks; emission_rate/decay_rates
  range tests; test_alive_filter_signal_creature_mass_floor_is_stricter;
  test_signal_retention_boosts_quality
- 389 passed, 0 pyright errors
SimOutput captures signal dynamics during simulation:
- signal_total_history: total signal mass per step (parallel to mass_history)
- signal_channel_snapshots: (n_snapshots, C) mean per channel at snapshot steps
- species_signal_received: (S, n_snapshots, C) mean signal over each species
  territory at snapshot steps (hetero only)

analytics.py: two new functions
- compute_signal_observables(): mass fraction, dominant channel history
- compute_signal_observables_hetero(): receptor alignment and
  emission-reception compatibility matrix

EcosystemMeasures: 6 new fields, all serialized to summary.json
build_index.py: reads and passes all new fields to ecosystem template
smoke_ecosystem.sh: verifies all signal fields present in summary.json
8 new tests in test_analytics.py

397 passed, 0 errors
@rkv0id rkv0id self-assigned this Apr 18, 2026
rkv0id added 7 commits April 18, 2026 15:05
ecosystem.html
- "total mass conserved" label replaced with context-aware message
  distinguishing signal-active runs from true mass-conserved runs
- SIGNAL badge: teal bordered badge appears in run header when
  has_signal_data is true, with tooltip explaining signal-enabled archives
- Outcome label tooltips: hover over any outcome badge shows plain-English
  description of what that label means (coexistence, exclusion, merger,
  fragmentation, cannibalism, stable_isolation, partial_clustering)
- Signal charts section (gated on has_signal_data):
  signal total history, signal mass fraction [0,1], receptor alignment
  per species per snapshot, emission-reception compatibility heatmap (S×S)
- Signal overlay checkbox on GIF viewport: toggles a teal overlay showing
  signal field active state with dominant channel and magnitude readout

archive.html
- SIGNAL badge in run header (reads has_signal from manifest.json)
- buildParamsTable extended: when params contain signal keys, renders a
  SIGNAL FIELD section with emission_rate scalar, per-channel bar charts
  for emission_vector (teal), receptor_profile (purple, symmetric ±1 range),
  decay_rates (amber), and signal kernel radius

render.py
- render_archive_page gains has_signal: bool = False parameter, passed
  to archive.html template

build_index.py
- _render_run reads signal_field from manifest.json, passes has_signal
  to render_archive_page
- outcome_tooltips dict passed to ecosystem template
- has_signal_data detection from signal_total_history

index.html (System tab)
- Signal field description updated: lists all 8 searchable signal params
  (emission_vector, receptor_profile, emission_rate, decay_rates,
  signal_kernel_*), mentions 800-step auto-selection, retention quality term

README
- v3.4.0 roadmap entry ticked with full feature list
- Test count: 397 tests, 0 warnings
…tem tab restructure

quality.py -- fully rewritten
  Three-component score replaces single-point compactness:
    non-signal: q = 0.6 × compactness + 0.4 × stability
    signal:     q = 0.5 × compactness + 0.3 × stability + 0.2 × retention
  compactness = min(compact(state_T/2), compact(state_T))
    Two-point minimum catches early-peak degraders that score 0.99 at T
    but were already diffuse at T/2. Key insight: almost all viable solitons
    score >0.95 at the final step, making single-point compactness nearly
    constant across the population. The midpoint term is where selection
    pressure actually comes from.
  stability = clip(1 - drift / 0.2, 0, 1)
    Continuous version of the persistent filter. Borderline survivors
    (drift=0.19) score near 0; rock-stable creatures (drift=0.01) score ~1.
  retention = clip(final_mass / initial_mass, 0, 1)
    Signal runs only. Penalises runaway emission.

descriptors.py
  RolloutTrace gains midpoint_state: np.ndarray | None = None

rollout.py
  Midpoint state captured at config.steps // 2, passed to RolloutTrace

test_quality.py -- 4 new tests
  midpoint degrader detection, stability term direction, unit interval,
  None midpoint fallback

docs/signal-field.svg -- new diagram
  One-step signal field mechanics in the existing visual language:
  mass↔signal exchange via emission (amber) and reception (purple),
  decay (red), conservation note, parameter labels

index.html
  System tab restructured with internal anchor mini-nav:
    Architecture · Search · Quality metric · Ecosystem · Signal field · Descriptors
  New Quality metric section: prose + math blocks with the full formula
  New Signal field section: parameter table in monospace math, step-by-step
    physics prose, diagram embed, observable descriptions
  Signal prose removed from Ecosystem section (now its own section)

build_index.py
  signal-field.svg loaded and passed to index template as svg_signal_field

README
  Quality metric section updated with formula code block
  Signal field section gains diagram reference
  Test count: 401
SimOutput gains signal_sum_snapshots: (n_snapshots, H//4, W//4) float32
  signal.sum(dim=-1) downsampled 4x, captured at every snapshot step in
  both homo and hetero loops. ~10KB per snapshot vs 2.3MB for full field.

_colorize_signal_frame(): teal colormap for homo, species-colored for hetero
  using the same SPECIES_PALETTE blended by downsampled ownership weights.

signal.gif generated alongside ecosystem.gif in _compute_outputs, upsampled
  4x back to match mass GIF dimensions.

build_index.py: signal.gif loaded as signal_gif_src, passed to template.

ecosystem.html:
  Mass/Signal tab toggle top-left of GIF viewport -- swaps ecoGif / ecoGifSignal
  visibility. Both GIFs are embedded; toggle is instant, no re-fetch.
  Signal overlay checkbox and canvas removed entirely (was decorative noise).
  Mass chart label: "mass field only · signal tracked separately".

smoke_ecosystem.sh: signal.gif presence asserted for signal-active runs.

401 passed, 0 errors, 0 warnings
@rkv0id rkv0id merged commit fdea2a1 into main Apr 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant