# TRACE_RUNNER.md

`./grownet.sh` is the preferred repo-root entry point for deterministic GrowNet tracing, benchmarking, and interactive probing.

- Preferred path: `./grownet.sh`
- Compatibility path: `./scripts/grownet.sh`
- Implementation detail: the root shim dispatches to `scripts/grownet.sh`

## Supported languages

- `--lang java`
- `--lang python`

## Unsupported launcher languages

- `--lang mojo`
- `--lang cpp`

The launcher accepts both tokens so the CLI surface stays stable, but they are intentionally not implemented in this repository yet.

- Exit code: `2`
- Message: `GrowNet trace runner: --lang <lang> is not implemented in this repository.`

The same not-implemented behavior applies to benchmark mode.

## Supported flags

- Mode flags:
  - `--trace`
  - `--benchmark`
  - `--interactive`
  - `--mode run|trace|benchmark|interactive`
- Shared scenario flags:
  - `--scenario single_neuron|two_layer|image_2d|growth`
  - `--value 0.42`
  - `--ticks 1`
- Config-driven experiment flags:
  - `--config path/to/experiment.json`
  - `--input path/to/input_file`
  - `--input-type sequence|tensor|image|audio`
  - `--output path/to/output_file_or_dir`
- `--debug`
- `--trace-format text|jsonl`
- `--trace-events tick,layer,neuron,slot,weight,threshold,tract,growth,prune,bus,focus,anchor`
- `--trace-events` also accepts exact event names such as `threshold.update`
- `--trace-signal`
- `--out stdout|path/to/file.log`
- `--trace-neuron E0`
- `--trace-layer 0`
- `--benchmark`
- `--benchmark-format text|jsonl`
- `--benchmark-warmup 100`
- `--benchmark-iterations 1000`
- `--benchmark-repeat 5`
- `--benchmark-output stdout|path/to/file.log`
- `--profile single_scalar|dual_scalar|growth_probe`
- `--config path/to/interactive_config.json`
- `--normalize-inputs normalized|raw`
- `--interactive-output compact|verbose|jsonl`
- `--interactive-trace on|off`
- `--help`

## Example commands

```bash
./grownet.sh --lang java --trace --scenario single_neuron --value 0.42
./grownet.sh --lang python --trace --scenario two_layer --value 0.42
./grownet.sh --lang java --trace --trace-format jsonl --trace-events slot,growth --scenario growth
./grownet.sh --lang python --trace --trace-format jsonl --trace-events threshold.update --scenario single_neuron --value 0.42
./grownet.sh --lang python --trace --trace-format jsonl --trace-events focus,anchor --config experiments/image_tensor.json
./grownet.sh --lang python --trace --trace-signal --scenario image_2d
./grownet.sh --lang java --benchmark --scenario single_neuron --benchmark-warmup 25 --benchmark-iterations 250 --benchmark-repeat 3
./grownet.sh --lang python --benchmark --benchmark-format jsonl --scenario growth --value 0.42 --ticks 2 --benchmark-output stdout
./grownet.sh --lang python --interactive
./grownet.sh --lang python --interactive --profile dual_scalar --interactive-output verbose
./grownet.sh --lang python --config experiments/single_scalar_sequence.json
./grownet.sh --lang python --trace --config experiments/single_scalar_sequence.json
```

If you need the implementation path directly, `./scripts/grownet.sh` remains supported as a compatibility entry point.

## Output formats

- `text` is the default. Each line is `[event.name] key=value ...`.
- `jsonl` writes one JSON object per line with the same event names and field meanings.

The shared schema lives in `docs/contracts/grownet.trace.schema.json`.

Focus V1 adds `focus.*` and `anchor.*` trace families for serial candidate selection and remembered-anchor behavior.

## Parity Scope

The trace runner validates shared trace semantics and shared schema.

- Text output is developer-facing and human-readable.
- JSONL output is the canonical parity format.
- Canonical JSONL parity checks contract-level behavior and shared trace schema.
- Internal implementation may differ across languages when that is consistent with GrowNet's language reference policy.

In particular:
- Python remains the Pythonic reference implementation.
- Mojo should remain very close to Python.
- Java remains the core semantic / architectural reference.

## Benchmark Mode

Benchmark mode is separate from trace mode.

- Trace mode explains what happened.
- Benchmark mode measures how fast a scenario ran.
- Benchmark mode reuses the same deterministic scenarios and shared scenario flags.
- Benchmark mode measures end-to-end per-iteration scenario construction plus `--ticks` tick execution inside one backend process.
- Trace is off by default during benchmarking and should usually stay off for fair performance comparison.
- If you enable `--trace` together with `--benchmark`, trace processing is included in the measured workload.
- To keep benchmark output parseable, trace-to-stdout is suppressed during benchmark mode. Use `--out path/to/file.log` if you explicitly want trace logs while benchmarking.
- Benchmark text and JSONL output are documented in `docs/BENCHMARK_RUNNER.md`.

## Interactive Mode

Interactive mode is the live probing mode.

- Interactive mode keeps a persistent GrowNet instance alive.
- Built-in profiles define the initial scaffold only; the network is still free to grow after the session starts.
- Reset rebuilds the original scaffold from the same profile/config and resets tick/input state.
- This PR implements interactive mode in Python first.
- `--lang java --interactive` currently returns a clear not-implemented message.
- Full usage is documented in `docs/INTERACTIVE_RUNNER.md`.

## Experiment Runner Mode

Config-driven execution is the shared experiment path for Python.

- `./grownet.sh --lang python --config ...` runs a batch experiment from config
- `--trace`, `--benchmark`, and `--interactive` can all reuse the same scaffold-oriented config fields
- the dedicated config/input documentation lives in `docs/EXPERIMENT_RUNNER.md`
- Java config-driven execution is not implemented in this PR

## Focus & Anchoring

Focus & Anchoring V1 is Python-first and additive.

- baseline `tick_2d()` remains the honest per-pixel path
- focus-aware 2D routing is enabled through experiment config rather than by silently changing baseline scenario behavior
- focus trace families are `focus` and `anchor`
- the dedicated model doc lives in [FOCUS_AND_ANCHORING.md](C:/Development/Projects/GrowNet/docs/FOCUS_AND_ANCHORING.md)

## Signal IDs

- Scalar ticks use `tick-000001`.
- Pixel-level image signals use `tick-000001:px-0000-0000`.

Signal IDs stay attached to traversal events so a single grep shows the path through slot selection, firing, delivery, growth, and end-of-tick accounting.

## Scenarios

- `single_neuron`: one scalar neuron, useful for slot creation and threshold updates.
- `two_layer`: one scalar neuron driving a downstream neuron through an explicit edge, useful for `neuron.fire` and `tract.deliver`.
- `image_2d`: deterministic per-pixel spatial inputs with pixel-scoped `signal_id` values.
- `growth`: fallback pressure plus neuron and region-driven layer growth events.

### `image_2d` limitation

`image_2d` is a deterministic spatial trace scenario, not a full traced windowed-tract or retina-style Java demo. In Java it currently focuses on per-pixel slotting, firing, and signal-id propagation rather than a richer downstream replay pipeline.

For benchmarking, `image_2d` is supported but still provisional for apples-to-apples language comparison because the Java scenario remains intentionally lightweight.

## Filtering

- `--trace-events` limits output to selected event families such as `slot` or `growth`.
- Exact event-name filters are also accepted, for example `threshold.update`.
- `--trace-neuron` keeps only events tied to the named neuron.
- `--trace-layer` keeps only events tied to the selected layer index.

## Notes

- Tracing is best-effort. Trace formatting and trace I/O failures are swallowed locally and must not throw into normal tick paths.
- Trace-off behavior is regression-tested for `single_neuron`, `two_layer`, and `growth`; tracing should not change runtime results.
- Fixture mismatch does not automatically mean Python must change. Classify the mismatch using `docs/LANGUAGE_REFERENCE_POLICY.md` and `docs/PARITY_DECISION_CHECKLIST.md` before changing runtime semantics.
- This follow-up intentionally keeps two non-trace semantic fixes from the original trace work:
  - Java `Layer.forward()` iterates a snapshot so growth during `forward()` does not throw and newly created neurons wait until the next tick.
  - Java neuron and region growth pressure honor the effective slot limit `slotLimit >= 0 ? slotLimit : cfg.getSlotLimit()`.
- The trace runner stays scenario-oriented and instruments the real Java/Python runtime rather than replacing it with a debug-only execution path.
