# PR: Finish Python Runtime / Demo Cleanup and Close Unfinished TODO-Style Work

## Title

cleanup: finish Python runtime/demo loose ends, normalize delivery contracts, and remove misleading placeholders

---

## Summary

This PR addresses unfinished or partially-implemented work found during a focused code pass over the GrowNet repo.

The issues are concentrated mostly in the **Python runtime / demo side** of the repository and include:

- placeholder metric accounting in `Region.tick()`
- a muddy `Neuron.fire()` / `Synapse.deliver()` contract
- stale demos that still treat `RegionMetrics` like a dict
- a misleading `tick_image()` shim that collapses a 2D frame into a mean scalar
- an adaptive slot-policy path that reads as experimental / incomplete
- `train_omniglot.py` depending on module-global CLI args
- stub / no-op behavior that should either be implemented or explicitly documented as intentional

This PR should clean that up **without** forcing Python to become Java-like.

---

## Important architectural rule

Respect GrowNet's language-reference model:

- **Java** = core semantic / architectural reference
- **Python** = Python-language-style reference
- **Mojo** should track Python almost one-to-one
- **C++** follows Java as much as practical

That means:

- do **not** Java-ize Python just because Java does something differently
- keep Python explicit and readable
- avoid clever one-liners
- prefer clear control flow and obvious data structures
- only align Python to Java when the difference is truly contract-level or semantically required

This PR is a **Python runtime / demo cleanup PR**, not a Java-forcing parity PR.

---

## Required reading before coding

Read these before implementation:

1. `docs/READ_ORDER.md`
2. `docs/LANGUAGE_REFERENCE_POLICY.md`
3. `docs/CODING_STYLE_MUST_READ.md`
4. `docs/GOLDEN_RULE.md`
5. `docs/GROWTH.md`
6. `docs/CREATION_AND_GROWTH_POINTS.md`
7. `docs/contracts/grownet.contract.v5.json`
8. `docs/GrowNet_Design_Spec_V5.md`
9. `docs/TRACE_RUNNER.md`
10. `docs/TRACE_PARITY.md`
11. `docs/PARITY_DECISION_CHECKLIST.md`

---

## Coding style requirements

These are mandatory:

- Follow `docs/CODING_STYLE_MUST_READ.md`
- No single- or double-character identifiers anywhere, including loops
- Keep Python explicit and readable
- Avoid clever one-liners
- Prefer small, obvious helper functions
- Preserve determinism
- Preserve two-phase tick discipline
- Do not introduce speculative redesign
- Do not force Python internals to mimic Java unless the difference is contract-required

---

## Scope

### Implement in this PR

1. real delivered-event accounting in Python runtime metrics
2. normalized `Synapse.deliver()` / caller contract
3. demo cleanup for `RegionMetrics`
4. honest and properly-scoped 2D image ticking behavior
5. adaptive slot-policy cleanup / clarification
6. `train_omniglot.py` CLI decoupling
7. explicit handling of stub/no-op paths that currently look unfinished
8. focused tests for all touched behavior

### Do not do in this PR

- Java runtime changes unless strictly needed for tests around shared Python behavior
- Mojo runtime changes
- C++ runtime changes
- broad parity redesign
- large architecture rewrites
- unrelated trace feature work

---

# Phase 1 — fix real metric accounting

## 1. Replace placeholder `delivered_events` accounting

There is a placeholder-style metric path where `delivered_events` is effectively derived from something like total synapse count instead of real deliveries.

Fix this.

### Goal

`Region.tick()` and related helpers must report **actual delivery activity**, not a placeholder proxy.

### Requirements

- Count real deliveries that occurred during the tick
- Do not use `total_synapses` as a stand-in
- Make scalar and spatial delivery accounting consistent
- Keep the implementation explicit and deterministic

### Likely files

- `src/python/region.py`
- `src/python/metrics.py`
- `src/python/neuron.py`
- `src/python/synapse.py`
- `src/python/tract.py`

### Preferred approach

Use explicit counting at actual delivery points.

Examples:
- direct synapse delivery
- tract delivery
- any layer propagation helper that truly delivers to targets

Do **not** infer delivered events indirectly from structure size.

### Tests

Add or update tests to verify:
- zero deliveries yields zero `delivered_events`
- one scalar fire with one target increments as expected
- multi-target delivery increments correctly
- spatial / tract-driven deliveries increment correctly

---

# Phase 2 — normalize `Neuron.fire()` / `Synapse.deliver()` contract

## 2. Fix the delivery contract so caller/callee responsibilities are clear

The current `Neuron.fire()` / `Synapse.deliver()` interaction is muddy.

Make the contract explicit and consistent.

### Requirements

Choose one clear rule and apply it consistently:

### Preferred
`Synapse.deliver(value)` returns whether the target fired, while the caller remains responsible for any follow-up that belongs in the caller.

or

### Alternative
`Synapse.deliver(value)` fully owns delivery semantics, and callers do not treat it like a boolean.

Pick one and normalize the code.

### Important

- No double-delivery
- No caller assuming a boolean if callee is side-effect-only
- No callee silently doing more than the API implies
- Keep it easy to read

### Likely files

- `src/python/neuron.py`
- `src/python/synapse.py`

### Tests

Add regression tests covering:
- one synapse delivery
- target fires vs target does not fire
- no duplicate delivery
- no broken behavior in downstream propagation

---

# Phase 3 — clean stale demos

## 3. Update demos that still treat `RegionMetrics` like a dict

Several demos appear to index metrics like:

```python
metrics["delivered_events"]
```

while `Region.tick()` returns a dataclass/object-like metrics result.

Clean those demos up.

### Likely files

- `src/python/demo_region.py`
- `src/python/region_demo.py`
- `src/python/image_io_demo.py`

### Requirements

- Use the actual `RegionMetrics` API consistently
- Do not rely on dict-like access unless that is an intentional supported API
- Keep demos runnable and clear

### If you decide dict-style access should be supported
Only do that if it is already an intentional repo design. Otherwise prefer updating demos.

### Tests / validation

- run demos if practical
- or add minimal smoke tests that ensure the demos no longer assume dict access

---

# Phase 4 — make `tick_image()` honest and useful

## 4. Resolve the misleading 2D image shim

Right now the image tick path appears to reduce a 2D frame to a mean scalar or similarly demo-like simplification.

This needs to be addressed.

### Goal

Make the API honest.

### Preferred path
Implement a true per-pixel / 2D execution path if the surrounding runtime already supports it cleanly.

### Acceptable fallback
If a full 2D path is not viable without broad redesign, then:

- split the API into an explicit shim and an explicit real path
- rename the scalarized path so it is obviously a convenience shim
- document the limitation clearly
- do **not** leave a misleading `tick_image()` name that implies full 2D processing if it is only averaging

### Requirements

- no misleading API behavior
- no hidden mean-intensity collapse under a name that sounds spatially real
- preserve determinism
- keep Pythonic clarity

### Likely files

- `src/python/region.py`
- `src/python/input_layer_2d.py`
- `src/python/input_neuron.py`
- any image demo file that uses this path

### Tests

Add tests for whichever final API you keep:
- true per-pixel path behavior, or
- explicit scalar-shim naming and behavior

---

# Phase 5 — clean up adaptive slot policy status

## 5. Resolve the “minimal adaptive skeleton” problem

The current adaptive slot policy reads as incomplete / experimental.

Address that explicitly.

### Acceptable outcomes

#### Option A — preferred if small and clear
Implement one small, deterministic refinement that makes the adaptive behavior feel intentionally complete for its current scope.

#### Option B — also acceptable
If the policy is genuinely experimental, explicitly mark it as such in docstrings/comments/tests and stop implying it is more mature than it is.

### Important

Do **not** over-engineer this.
Do **not** introduce a big adaptive policy redesign.

The goal is clarity and intentionality.

### Likely files

- `src/python/slot_policy.py`

### Tests

Add focused tests around whichever behavior is declared canonical.

---

# Phase 6 — fix `train_omniglot.py` global-args coupling

## 6. Remove module-global `args` dependency from `run_few_shot()`

`run_few_shot()` should not depend on CLI globals created later in `__main__`.

### Requirements

- pass needed parameters explicitly, such as `log_every`
- keep the function reusable
- keep CLI behavior unchanged for script users

### Likely file

- `src/python/train_omniglot.py`

### Tests / validation

- ensure script still runs
- if no formal test exists, at least make the function independently callable without `args` being globally defined

---

# Phase 7 — clean up stub/no-op paths

## 7. Handle obvious stub/no-op methods intentionally

If something like `InputLayer2D.end_tick()` is `pass`, do one of the following:

### If no-op is truly correct
Add an explicit comment/docstring saying the no-op is intentional and why.

### If behavior is actually needed
Implement the minimal correct behavior.

The goal is to eliminate “looks unfinished” ambiguity.

### Likely files

- `src/python/input_layer_2d.py`
- any other touched Python files with `pass`, TODO, FIXME, or “reserved for later” comments in the affected path

---

# Phase 8 — search and classify nearby unfinished work

## 8. Search targeted Python runtime/demo files for unfinished markers

Search the touched area for:

- `TODO`
- `FIXME`
- `reserved for later`
- `NotImplementedError`
- suspicious `pass`
- comments implying placeholder accounting

### Important

Do **not** explode scope across the whole repo.
Restrict this search to the files you are already touching and immediately adjacent runtime/demo files.

For each relevant occurrence:
- implement it if it is small and clearly needed
- or make it explicitly intentional and documented
- or leave it alone if it is truly abstract/base-class behavior that is correct as-is

---

# Tests to add / run

At minimum, add/update tests covering:

1. real `delivered_events` accounting
2. `Synapse.deliver()` contract normalization
3. stale demo metric access no longer broken
4. 2D tick path behavior or explicit shim behavior
5. adaptive slot policy intended behavior
6. `train_omniglot.py` no longer depends on global `args`
7. any no-op/stub path you made explicit or implemented

### Existing tests to run if present

Run the relevant Python test files for:
- region ticking
- growth
- spatial focus
- frozen slots
- image / ND ticking
- demos if they have tests

If tests do not exist, add focused ones rather than hand-waving.

---

## Acceptance criteria

This PR is complete when:

1. `Region.tick()` no longer reports placeholder `delivered_events`
2. `Neuron.fire()` / `Synapse.deliver()` contract is explicit and consistent
3. demo files no longer treat `RegionMetrics` like a dict unless that is intentionally supported
4. `tick_image()` is either truly 2D or explicitly and honestly a shim
5. adaptive slot policy is either minimally completed or explicitly marked experimental
6. `run_few_shot()` no longer depends on module-global `args`
7. obvious touched-path stub/no-op ambiguity is resolved
8. tests cover the new intended behavior
9. Python remains readable, explicit, and Pythonic

---

## Suggested commit structure

1. fix metric accounting and delivery contract
2. clean demos and 2D path
3. slot-policy and training-script cleanup
4. tests and docs/comments cleanup

---

## Final response expected from Codex

At the end, provide:

1. summary of what changed
2. files changed
3. which unfinished items were fully implemented
4. which items were explicitly documented as intentional rather than expanded
5. tests run
6. any remaining nearby TODO-style work you deliberately left untouched and why
